Analysis of Data Quality
The Correlates of War datasets are a product of the Correlate of War Project (COW) founded in 1963. COW’s goal is to “facilitate the collection, dissemination, and use of accurate and reliable quantitative data in international relations.” [Correlates of War Project] From the COW datasets we focused on 4 datasets: National Materials Capabilities, Militarized Interstate Disputes, Alliances and Trade. As these data sets are part of the COW project, the authority, accuracy and objectivity of the data sets are impeccable. All the data sets use a field called country code, a numeric ID given to each country. This is a consistent field that can be used to tie the data across the data sets in the COW project.
National Materials Capabilities
The overall data quality of NMC dataset is very good. There are roughly 14,000 entries and 89% of them did not have any missing values. There is one data entry for each country per year. The accuracy of the data is also very good because as countries are dissolved and new ones are formed, this data keeps track of them. For example, the graph depicts the CINC of Austria-Hungary from 1900-1918, the end of WWI when it the Austro-Hungarian Empire was dissolved. Immediately after that, you see data points for Austria and Hungary separately. This same accuracy hold true for many different countries, where there is only data once the country has declared independence or has just been created.
NMC_test <- NMC_orig
NMC_test$cinc[NMC_test$cinc == -9] <- NA
NMC_test$irst[NMC_test$irst == -9] <- NA
NMC_test$milex[NMC_test$milex == -9] <- NA
NMC_test$milper[NMC_test$milper== -9] <- NA
NMC_test$pec[NMC_test$pec == -9] <- NA
NMC_test$tpop[NMC_test$tpop == -9] <- NA
NMC_test$upop[NMC_test$upop == -9] <- NA
NMC_test <- filter(NMC_test, NMC_test$year %in% c(1900:2007))
test <- c("Austria-Hungary", "Austria", "Hungary")
test_ccode <- member_alliances$ccode[match(test, member_alliances$state_name)]
NMC_test <- filter(NMC_test, NMC_test$ccode %in% test_ccode)
ggplot() +
scale_x_continuous(name="Year") +
scale_y_continuous(name="CINC") +
labs(color ='Country Abbreviation')+
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=0, ymax=.09, fill=Conflict),alpha=0.15) +
geom_line(data = NMC_test, aes(x = year, y = cinc, color = stateabb, group = stateabb)) +
ggtitle("CINC for Austria-Hungary") +
theme_classic()+
scale_fill_manual(values=c("salmon", "paleturquoise3", "lightsteelblue2", "lightsteelblue4", "lightsteelblue3", "pink3"))+
scale_color_brewer(palette="Paired")+
theme(plot.title = element_text(hjust = .5), legend.position = "bottom")

Below is heat map of CINC values for a few countries and we can see that there are missing CINC values for certain countries. More specifically, this the heat map below shows the CINC values of countries that were destroyed by both the Holocaust and the fight for freedom from Communism. These countries had to go through a period of major reformation and recovery. In the data set, anytime that a country has been devastated it has missing CINC values.
topCas <- c("Netherlands", "Yugoslavia", "Lithuania", "Poland", "Austria", "Hungary", "Romania", "Estonia", "Luxembourg")
topCas_ccode <- member_alliances$ccode[match(topCas, member_alliances$state_name)]
NMC_cas <- filter(NMC_orig, NMC_orig$year %in% c(1900:2012))
NMC_cas <- filter(NMC_cas, NMC_cas$ccode %in% topCas_ccode)
for( i in c(1:length(topCas_ccode))){
NMC_cas$country[NMC_cas$ccode == topCas_ccode[i]] <- topCas[i]
}
ggplot(NMC_cas, aes(country, year, fill = cinc)) + geom_tile()+
xlab("Country") +
ylab("Year") +
scale_fill_viridis() +
ggtitle("CINC Heatmap for Countries with the most Holocaust Casualties") +
theme_classic()+
theme(plot.title = element_text(hjust = 0.5)) +
coord_flip() +
labs(color ='CINC')

NA
Alliances
There are 6 iterations of the same data, each serving a different purpose. The Alliances contains the alliance dataset distributed by member, with one observation for each alliance member initiation. There is also another file with same data but includes an additional field that has an observation for each year the member is in the alliance. There is another data set with one observation for each dyadic alliance initiation. This data set also list the details of the alliances. As with the alliances data set, the dyadic alliances data set contains another file that has an observation for each year the member is in the alliance. Finally, there is the directed dyad data set that has 2 observations per alliance, where it details the terms of the alliance of country A towards country B, then another point to details the terms of agreement of country B towards country A. As with the other alliances data sets, there is another directed dyad data set with one observation for each year the alliance is in effect. From all the data we have looked at it in our analysis, the data shows information that is in line with historical events.
Some of the inconsistencies that I noticed are in cases where the alliance is still in effect as of the 12/31/2012, which was when this data set was last updated. In some of the datasets, if the alliance is ongoing, it would have the dyad_end_year, the field that represents the year in which the alliance was terminated, set to 2012 and in other data sets it would have it set as ‘NA’. In the case that dyad_end_year is set to 2012, it was hard to know if there were any alliances that ended in 2012 or if they were an ongoing alliance.
Militarized Interstate Disputes (MID)
The MID data is thorough and well collated. As conflicts or wars can have multiple dimensions to them, the MID data is broken down into 2 main data sets. MIDA contains an observation per conflict with details about the start and end of the conflict, the fatalities, the outcomes, the settlements, the highest action taken etc. The other part of the dataset- MIDB, contains one observation per actor in a conflict, thus adding a different dimension to the data.

As seen above, the authors of the dataset have used techniques to categorize certain subjective variables and then futher factor them to the number format. For instance, the “Outcome” of a dispute was factored as follows [Palmer, Glenn]:
Victory for side A: 1
Victory for side B: 2
Yield by side A: 3
Yield by side B: 4
Stalemate: 5
Compromise: 6
Released: 7
Unclear: 8
Joins ongoing war: 9
Missing: -9
That created a conformity among all recorded obervations which made it easier to work with.
Another arrangement that made the data effective was that certain datapoints were clearly marked unclear or missing and based on the context of the graph, we were able to easily sift through them.
Main Analysis
National Materials Capabilities
NMC <- NMC_orig
NMC$cinc[NMC$cinc == -9| is.na(NMC$cinc)] <- 0
NMC$irst[NMC$irst == -9| is.na(NMC$irst)] <- 0
NMC$milex[NMC$milex == -9| is.na(NMC$milex)] <- 0
NMC$milper[NMC$milper== -9| is.na(NMC$milper)] <- 0
NMC$pec[NMC$pec == -9| is.na(NMC$pec)] <- 0
NMC$tpop[NMC$tpop == -9| is.na(NMC$tpop)] <- 0
NMC$upop[NMC$upop == -9| is.na(NMC$upop)] <- 0
all_year <- c(1900:2007)
NMC_ratios <- c("")
for (year_t in all_year){
yr <- filter(NMC, NMC$year %in% year_t)
max <- apply(yr[, c(4:9)], 2, sum)
#max <- as.numeric(max[4:9])
for (i in 4:9){
yr[,i] = as.numeric(yr[,i]/max[i-3])
}
NMC_ratios <- smartbind(NMC_ratios , yr)
}
NMC_ratios <- NMC_ratios [c(2:nrow(NMC_ratios )), c(2:length(NMC_ratios))]
cbbPalette <- c("#000000", "#E69F00", "#56B4E9", "#009E73", "#F0E442", "#0072B2", "#D55E00", "#CC79A7")
National Materials Capability measures the power of a country based on 6 values: total population, urban population, military personnel, military expenditures, iron and steel production and energy consumption. NMC is purely a measure of military and economic means of influence rather than diplomacy or other forms of influence.
CINC is the composite score to measure the power of a country using the average of the ratios of each country value to the total value of all countries for each of the 6 factors. Below is the CNIC score for major powers today who also participated the major wars in the past. Also highlighted are the period wars mentioned above.
countries <- c("United States of America", "United Kingdom", "France", "Russia","Germany", "Japan", "China")
country_code <- member_alliances$ccode[match(countries, member_alliances$state_name)]
NMC_mp <- filter(NMC, NMC$year %in% all_year)
NMC_mp <- filter(NMC_mp, NMC_mp$ccode %in% country_code)
NMC_mp$country = ""
for( i in c(1:length(country_code))){
NMC_mp$country[NMC_mp$ccode == country_code[i]] <- countries[i]
}
ggplot() +
scale_x_continuous(name="Year") +
scale_y_continuous(name="CINC") +
labs(color ='Country')+
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=0, ymax=max(NMC_mp$cinc), fill=Conflict),alpha=0.15) +
geom_line(data = NMC_mp, aes(x = year, y = cinc, color = country, group = stateabb)) +
ggtitle("CNIC by Year for Major Powers Today") +
theme_classic()+
scale_fill_manual(values=c("salmon", "paleturquoise3", "lightsteelblue2", "lightsteelblue4", "lightsteelblue3", "pink3"))+
scale_color_brewer(palette="Paired")+
theme(plot.title = element_text(hjust = .5), legend.position = "bottom")

NA
As you can see CNIC is constantly changing. Interestingly, the CNIC spikes for the US right after WWI and WWII where the US had a major role in the outcome of the wars. There is also an increase in the US’s CINC score during the Korean War. Following the Korean War, the US’s CINC score shows a continuous decrease during the Vietnam where the US lost the war. At the end of WWI, you see Russia’s CNIC dip low but it bounced back to its CNIC before WWI quickly. During the Vietnam War, Russia supported the Vietnamese people and you see the its CINC score increase above that of the US as they start to gain ground in the war. Also, Russia’s CINC score drops low towards the end of the Cold War as the satellite states start gaining their independence and the USSR was dissolved (Battlefield: Vietnam).
To explore the trends more, the data was refined to only look at the major participants of each war. For example, with WWI we looked at the CINC values for major players in the Allied Powers and Central Powers a few years before and after the war. We replicated this process for all the events listed above. Below are CINC graphs using this approach for WWI and WWII.
allied <- c("United States of America", "United Kingdom", "Russia", "Japan", "Italy")
allied_ccode <- member_alliances$ccode[match(allied, member_alliances$state_name)]
central <- c("Germany", "Turkey", "Austria-Hungary", "Romania", "Bulgaria")
central_ccode <- member_alliances$ccode[match(central, member_alliances$state_name)]
WWI_range = c(1904:1930)
WWI<- filter(NMC, NMC$year %in% WWI_range)
alliedP<- filter(WWI, WWI$ccode %in% allied_ccode)
alliedP$side = "Allied Powers"
for( i in c(1:length(allied_ccode))){
alliedP$country[alliedP$ccode == allied_ccode[i]] <- paste(allied[i],"(Allied)", sep = " ")
}
centralP<- filter(WWI, WWI$ccode %in% central_ccode)
centralP$side = "Central Powers "
for( i in c(1:length(central_ccode))){
centralP$country[centralP$ccode == central_ccode[i]] <- paste(central[i], "(Central)", sep = " ")
}
WWI <-rbind(alliedP, centralP)
ww1 <- ggplot() +
labs(color ='Country')+
xlab("Year") +
ylab("CNIC")+
geom_rect(data=d, mapping=aes(xmin=1914, xmax=1918, ymin=0, ymax=.4),alpha=0.05, fill ="salmon") +
geom_line(data = WWI, aes(x = year, y = cinc, color = country, group = country)) +
facet_wrap(~side) +
theme_classic()+
scale_color_brewer(palette="Paired")+
ggtitle("CNIC Score: WWI Major Players ")+
theme(plot.title = element_text(hjust = .5),legend.position="right")
allies <- c("United States of America", "United Kingdom", "France", "Russia", "Australia","China")
allies_ccode <- member_alliances$ccode[match(allies, member_alliances$state_name)]
axis <- c("Germany", "Italy", "Japan", "Hungary", "Romania", "Bulgaria")
axis_ccode <- member_alliances$ccode[match(axis, member_alliances$state_name)]
WWII_range = c(1934:1950)
WWII<- filter(NMC, NMC$year %in% WWII_range)
alliedP2<- filter(WWII, WWII$ccode %in% allies_ccode)
alliedP2$side = "Allies"
for( i in c(1:length(allies_ccode))){
alliedP2$country[alliedP2$ccode == allies_ccode[i]] <- paste(allies[i], "(Allies)", sep = " ")
}
axisP<- filter(WWII, WWII$ccode %in% axis_ccode)
axisP$side = "Axis"
for( i in c(1:length(axis_ccode))){
axisP$country[axisP$ccode == axis_ccode[i]] <- paste(axis[i], "(Axis)", sep = " ")
}
WWII <-rbind(alliedP2, axisP)
ww2 <- ggplot() +
labs(color ='Country')+
xlab("Year") +
ylab("CNIC")+
geom_rect(data=d, mapping=aes(xmin=1939, xmax=1945, ymin=0, ymax=.4),alpha=0.05, fill ="paleturquoise3") +
geom_line(data = WWII, aes(x = year, y = cinc, color = country, group = stateabb)) +
facet_wrap(~side) +
theme_classic()+
scale_color_brewer(palette="Paired")+
ggtitle("CNIC Score: WWII Major Players ")+
theme(plot.title = element_text(hjust = .5),legend.position="right")
grid.arrange(ww1, ww2, nrow=2)

As mentioned, with WWI the US’s CINC spiked right after the war and then began to steadily decrease till the beginning of the WWII. Russia’s CINC dropped but rose again quickly and stayed on a relatively upward trend till WWII. Unlike the US and Russia, United Kingdom’s CINC was steadily decreasing after the war. Italy and Japan’s CINC remained steady. With the Central Powers after WWI, Germany’s CINC dropped but it did not rise again. Turkey’s, Romania’s and Bulgaria’s CINC remained steady. We see the Austria-Hungarian CINC disappear after the war since the Austro-Hungarian empire was dissolved at the end of the war (Royde-Smith).
With WWII, we see a similar pattern for the US where the CNIC reaches a peak at the end of WWII and steadily decreases till the Korean war. Russia also shows a similar pattern to WWI where its CINC score reaches a low point towards the end of WWII and then continues to steadily increase till the Korean war. The UK also follows a similar pattern where it CINC peaks right after the war and then steadily decreases throughout the Cold War time period. With the Axis powers, Germany’s and Japan’s CINC drops off.
To explore the patterns above, we considered the components that make up the CINC. We chose to focus on the major powers because they had the most drastic changes during this period. We looked at both the actual value and the ratio because the absolute values gradually increased over time but the ratios show performance relative to the other countries each year. Looking at the ratios helped us to see trends that were not easy to spot when looking at the overall values. Below is a plot of five of the six CINC components, the values and the ratios
grid.arrange(arrangeGrob(ias, ias_r, mex, mex_r, mip, mip_r + theme(plot.title = element_text(hjust = .5), legend.position="none"),nrow=3, ncol =2),mylegend, heights=c(10,1))

#grid.arrange(ias, ias_r, mex, mex_r, mip, mip_r, urp, urp_r, top, top_r, nrow=6)
With the Iron and Steel Production ratio, you can see that it follows to same pattern as the CINC for the US during this period. The ratio peaks towards the end of WWI and WWII and decreases in the period between the two wars. Till about the beginning of the Vietnam War, roughly 1955, the US dominated the world in Iron and Steel production and so this value had huge impact the US’s CINC score. Generally, during most wars, the US has the most military production but lost its position toward s the end of the Vietnam war when Russia surpassed the US. The United Kingdom maintained its iron and steel production, but since USA and Russia were increasing their production, the UKs ratio has been steadily decreasing since the 1900s, very similar to that of the pattern observed with the CINC score.
Looking at military expenditure we see that the US and Russia had been significantly investing more in the military throughout the cold war. On the other hand, both countries decrease their military personnel after they peaked at the end of WWII. These findings are consistent with the Cold War where the US and Russia were in an arms race where they heavily invested in military technology but did not engage in any large-scale battles. The US’s military expenditures ratio peaks the same year its CINC score and iron and steel production ratio.
In the few years before WWII, you see Germany’s military expenditures ratio increase quite rapidly and the military personnel ratio saw a drastic increase in the one year before increasing quite rapidly. Although not as drastic, Japan and China follow a similar pattern where the military investment increased significantly a few years prior to WWII and the Korean War, respectively, and the military personnel ratio drastically increased right before the wars. This suggests that in years before the wars, these countries started investing in and preparing their militaries for war. The countries that were on the reactive side, the US, Russia and the UK, their military production ratios and military expenditures ratios only increased during the war.
NMC_v<- filter(NMC_ratios, NMC_ratios$year %in% c(1970:2000))
NMC_ratios_v<- filter(NMC_ratios, NMC_ratios$year %in% c(1970:2000))
#names <- c("North Korea", "South Korea", "Afghanistan" , "Vietnam", "Republic of Vietnam")
#code<- c(731, 732,700, 816, 817)
names <- c("Iraq")
code <- c(645)
NMC_v<- filter(NMC_v, NMC_v$ccode %in% code)
NMC_ratios_v<- filter(NMC_ratios_v, NMC_ratios_v$ccode %in% code)
for( i in c(1:length(code))){
NMC_ratios_v$country[NMC_ratios_v$ccode == code[i] ]<- names[i]
NMC_v$country[NMC_v$ccode == code[i] ]<- names[i]
}
a<- ggplot() +
scale_x_continuous(name="Year") +
scale_y_continuous(name="Ratio") +
geom_line(data = NMC_ratios_v, aes(x = year, y = milex), colour = "indianred3") +
ggtitle("Iraq Military Expenditures Ratio") +
geom_rect(data=d, mapping=aes(xmin=1990, xmax=1991, ymin=0, ymax=.025),alpha=0.03) +
theme_classic() +
theme(plot.title = element_text(hjust = .5, size =10 ), axis.text.x =element_text(size =6), axis.text.y =element_text(size =6), axis.title.x =element_text(size =8), axis.title.y =element_text(size =8), legend.position="none")
b<- ggplot() +
scale_x_continuous(name="Year") +
scale_y_continuous(name="Ratio") +
geom_line(data = NMC_ratios_v, aes(x = year, y = milper), colour= "royalblue3") +
ggtitle("Iraq Military Personnel Ratio") +
geom_rect(data=d, mapping=aes(xmin=1990, xmax=1991, ymin=0, ymax=.05), alpha=0.03) +
theme_classic() +
theme(plot.title = element_text(hjust = .5, size =10 ), axis.text.x =element_text(size =6), axis.text.y =element_text(size =6), axis.title.x =element_text(size =8), axis.title.y =element_text(size =8), legend.position="none")
grid.arrange(a,b,nrow = 1)

We wanted to see if this this same pattern was present in other conflicts. During the Gulf War, Iraq invaded Kuwait and it was met with international condemnation and the US and other nations joined forces to stop Iraq (Persian Gulf War). But before the invasion in war we see Iraq’s military expenditures and personnel ratios increasing. The gray shaded box indicates the period of the Gulf War (1990-1991). In the 1980s, Iraq’s military expenditure ratio drastically increased and then there was a sudden spike in military personnel right before the start of the war.
ct <- c("United States of America", "United Kingdom", "France", "Russia","Germany", "Italy", "Japan", "China")
ct_ccode <- member_alliances$ccode[match(ct, member_alliances$state_name)]
NMC_ct <- filter(NMC, NMC$year %in% all_year)
NMC_ct <- filter(NMC_ct, NMC_ct$ccode %in% ct_ccode)
for( i in c(1:length(ct_ccode))){
NMC_ct$country[NMC_ct$ccode == ct_ccode[i]] <- ct[i]
}
a<- ggplot(NMC_ct, aes(country, year, fill = cinc)) + geom_tile()+
xlab("Country") +
ylab("Year") +
scale_fill_viridis() +
ggtitle("CINC Heatmap for Major Powers") +
theme_classic()+
theme(plot.title = element_text(hjust = 0.5))+
coord_flip() +
labs(color ='CINC')
topCas <- c("Netherlands", "Yugoslavia", "Lithuania", "Poland", "Austria", "Hungary", "Romania", "Estonia", "Luxembourg")
topCas_ccode <- member_alliances$ccode[match(topCas, member_alliances$state_name)]
NMC_cas <- filter(NMC_orig, NMC$year %in% all_year)
NMC_cas <- filter(NMC_cas, NMC_cas$ccode %in% topCas_ccode)
for( i in c(1:length(topCas_ccode))){
NMC_cas$country[NMC_cas$ccode == topCas_ccode[i]] <- topCas[i]
}
b<- ggplot(NMC_cas, aes(country, year, fill = cinc)) + geom_tile()+
xlab("Country") +
ylab("Year") +
scale_fill_viridis() +
ggtitle("CINC Heatmap for Countries with the most Holocaust Casualties") +
theme_classic()+
theme(plot.title = element_text(hjust = 0.5)) +
coord_flip() +
labs(color ='CINC')
grid.arrange(a,b, nrow = 1 )

Finally, using the heat maps, we looked at impact on CINC after a war. On the left is a heat map of the major powers. You can see that France, Germany and Japan had missing CINC values at the end of World War II. Those periods of missing values correspond to the recovery period for each of those countries following the war. Next, we looked to see what other countries had gaps in their CINC data. Most of the countries that have missing gaps are Eastern European countries that where heavily impacted by the Holocaust and by the struggle to end Communism in the region (Royde-Smith). This indicates that for countries that are going through intense destruction or reformation, they do not have any CINC information.
Conclusions & Next Steps
To get even more into detail and context around certain characteristics, we want to look at specific events like pearl harbor or China’s invasion of Malaysia and other pivotal moments in wars to see how those events impact the CINC and its various components.
A problem with NMC is that there are many other factors that determine a power of a nation rather than the 6 NMC factors. One of the major considerations that is not considered is the diplomatic relation between countries. Diplomatic relations play a major role is the prevention and conclusion of conflicts. With this data, it was not possible to factor that in.
Additionally, another thing to consider is differences in policies between different countries. We see that military expenditures have been increasing for the US since the Cold War but Russia’s military expenditures take a sudden drop at the end of the Cold War. Since the end of the Cold War, Russia has been cutting military spending till today (Royde-Smith). Even with its participation in the Afghanistan War, Russia’s military expenditures have not increased. On the contrary, in the US today, politicians are proposing a Federal Budgets with increases in military spending. This difference is due to differences in policies of the countries. Thus, the reactions of countries to events will drastically vary based on their policies and it because hard to distinguish an overall pattern.
Another drawback of NMC is that it cannot consider changes in universal priorities. For example, with an increased concern for climate change and scare natural resources and with advancements in technology, iron and steel production might start to decrease drastically in the future so it may no longer be a valid measure of power. Similarly, advancements in technology would decrease the need for military personnel. The issue with NMC is that it cannot take such policy concerns and changes into consideration to measure national power.
Alliances
dayd_al_year <- filter(dyad_al_year, dyad_al_year$year %in% c(1900:2012))
dyad_al_year$length = dyad_al_year$dyad_end_year - dyad_al_year$dyad_st_year
dayd_al_year$conflict <- "0"
dyad_al_year$count <- 1
dir_alliances <- gather(dir_al_year, treaty_type, idicator, defense:entente)
dir_alliances <- dir_alliances[!dir_alliances$idicator %in% 0,]
dir_alliances$dyad_end_year[dir_alliances$dyad_end_year %in% NA] = 2016
dir_alliances <- dir_alliances[dir_alliances$year>1900,]
alliance_count <- dir_alliances[, c(2,3,14,16)]
alliance_count$count <- 1
gp_ct <- aggregate(cbind(count) ~ ccode1+state_name1+year+treaty_type, data =alliance_count, FUN = sum )
gp_ct$Conflict <- "0"
for(i in c(1:length(d$x1))){
gp_ct[gp_ct$year >= d$x1[i] & gp_ct$year <= d$x2[i], length(gp_ct)] <- as.character(i)
}
WWI was triggered by the assassination of the Archduke Franz Ferdinand of Austria. His death set off diplomatic crisis as countries that were not involved in the original conflict were forced to get involved. Once Austria declared war on Serbia for the death of the Arch Duke, Russia had to step into defend Serbia. Once Russia entered the conflict, Germany was forced to enter the conflict due to its alliance with Austria. During the conflict Germany invaded Belgium; in response, the United Kingdom mobilized due to their alliance with Belgium. This pattern continued to eventually involve all the major powers of the world for a devastating battle. Such alliances were the cause of World War I. Since then the number of Alliances has only grown and continues to grow. For this reason, we wanted to look at alliances and see how they change during wars.
Below is boxplot of the total number of alliances that are in effect each year between any two countries. It is easy to see that the median number of alliances jumped up significantly during WWII and continued to grow during the Cold War and remained relatively level since then. An interesting pattern is that the median number of alliances increased more in the 1-3 before the end of war. You can see this pattern with WWI, Korean War, Vietnam War and the end of the Cold War. Although the Cold War was only a state of severe political war there were many regional battles and the threat of a large-scale military war was constant. The number of alliances significantly increased from the start of the Cold War till the end.
ggplot() +
xlab("Year") +
ylab("Count")+
geom_boxplot(data = gp_ct, aes(x = as.factor(year), y = count, fill = Conflict)) +
ggtitle("Total Alliances by Year") +
theme_classic()+
theme(plot.title = element_text(hjust = .5, size = 20), axis.text.x = element_text(angle = 90, size = 10), axis.text.y = element_text(size = 15), axis.title.y = element_text(size = 15), axis.title.x = element_text(size = 15), legend.position="bottom", legend.text = element_text(size=15), legend.title = element_text(size=15))+
scale_fill_manual(values=c("white", "lightsteelblue3", "pink3", "paleturquoise3", "lightsteelblue2", "lightsteelblue4","salmon" ), labels = mylables)

Next we looked at the types of alliances formed during this time. The COW data reports on 4 types of alliances: defense, neutrality, entente and non-aggression. In a defense alliance, the member states agree to defend one or more states in alliance in the event of a conflict. With a neutrality alliance, there is an agreement to maintain neutrality towards the members of the alliance. In non-aggression alliance, the members agree to take no military action against one another. Finally, with an entente alliance there is an understanding that the states would consult with one another if a crisis occurred (Formal Alliances).
The plots below show the number of alliances by alliance type. The top row shows the number of new alliances that were formed each year and the second row shows number of alliances that were terminated that year. Please note that if an alliance was formed between 4 states then there would 6 new alliances in the data set because there is an alliance between each of the 4 members. Similarly, if an alliance between 4 states were terminated that would be 6 less alliances.
dir_al_0 <- filter(dir_al, dir_al$dyad_st_year %in% c(1900:2012))
all_st <- gather(dir_al_0, treaty_type, idicator, defense:entente)
all_st <- all_st[!all_st$idicator %in% 0,]
all_st$dyad_end_year[all_st$dyad_end_year %in% NA] = 2016
al_st_count <- all_st[, c(3,5,8,11,15)]
al_st_count$count <- 1
gp_st <- aggregate(cbind(count) ~ dyad_st_year+treaty_type, data =al_st_count, FUN = sum )
a <- ggplot() +
xlab("Year") +
ylab("Count")+
geom_bar(data = al_st_count, aes(x = dyad_st_year)) +
ggtitle("Total Alliances by Year they started")+
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=0, ymax=max(450), fill=Conflict),alpha=0.2)+
ggtitle("Number of Alliances Formed") +
theme_classic()+
theme(legend.position="bottom", plot.title = element_text(hjust = .5)) +
scale_fill_manual(values=c("salmon", "paleturquoise3", "lightsteelblue2", "lightsteelblue4", "lightsteelblue3", "pink3")) + facet_wrap(~treaty_type, nrow = 1 )
b<- ggplot() +
xlab("Year") +
ylab("Count")+
geom_bar(data = al_st_count[al_st_count$dyad_end_year < 2016, ], aes(x = dyad_end_year)) +
ggtitle("Number of Alliances Terminated")+
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=0, ymax=max(450), fill=Conflict),alpha=0.2)+
theme_classic()+
theme(legend.position="bottom", plot.title = element_text(hjust = .5)) +
scale_fill_manual(values=c("salmon", "paleturquoise3", "lightsteelblue2", "lightsteelblue4", "lightsteelblue3", "pink3")) + facet_wrap(~treaty_type, nrow = 1)
grid.arrange(a,b, nrow =2)

Most of the alliances formed were at the end of WWII and during the Cold War. Also, the most frequently formed alliances were defense and entente. Surprisingly, in years that see a large increase in the number of alliances formed there is also an increase in the number of alliances that were terminated. To dig in further to get a better understand of what types of treaties were formed and why they ended, we looked at individual countries.
The following charts are all organized the same way, they show a timeline of when the alliances started till either the end of the alliance (shown in red) or till 2012 if the alliance was observed in effect as of December 31, 2012 (shown in blue). The charts are facetted to show the different types of alliances because many of the alliance types overlap. For example, one alliance could be both a defense and entente alliance, so to get a better visual representation we separated the types of alliances. We focused this part of the analysis on the United States because it is a major power and thus is involved in many of the military alliances throughout history.
United States of America
al_us_yr <- filter(dir_al_year, dir_al_year$state_name1 %in% "United States of America")
al_us_yr <- gather(al_us_yr, Treaty, idicator, defense:entente)
al_us_yr <- al_us_yr[!al_us_yr$idicator %in% 0,]
al_us_yr$dyad_end_year[al_us_yr$dyad_end_year %in% NA] = 2016
al_us_yr <- al_us_yr[, c(1,5,8,11,14,16)]
al_us_yr$count = 1
al_us_yr$Status <- ""
al_us_yr$Status[al_us_yr$dyad_end_year < 2012] <- "Ended"
al_us_yr$Status[al_us_yr$dyad_end_year== 2012] <- "Ongoing"
ggplot() +
xlab("Year") +
ylab("Country")+
geom_point(data =al_us_yr, aes(x=year, y = state_name2, color =Status), alpha = .5) +
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin="Afghanistan", ymax="Zimbabwe", fill=Conflict),alpha=0.15) +
ggtitle("US Alliances ")+
theme_classic()+
scale_fill_manual(values=c("salmon", "paleturquoise3", "lightsteelblue2", "lightsteelblue4", "lightsteelblue3", "pink3")) + facet_wrap(~treaty_type, nrow = 1)+
facet_wrap(~Treaty, nrow = 1 ) +
theme(legend.position="right", plot.title = element_text(hjust = .5))

Looking at the alliances for the US, we see that most defense alliances are still in effect today. There were handful of alliances with South American countries that ended towards the end of WWII but the US entered a different alliance with those same countries immediately. The treaties in effect with the South American countries is the Inter-American Treaty of Reciprocal Assistance (Rio Pact) where if there is an attack against one country, it is considered an attack among all the Americas countries in the alliance. This alliance was created n 1949 and continues till today (The Rio Pact at a Glance).
You can also see a similar pattern of ongoing alliances for defense entente and nonaggression treaty types. NATO, a defensive, entente and nonaggression alliance, was formed in 1947 and is still in effect till today. NATO involves 28 countries and accounts for the high number of alliances formed in 1949 for the 3 types (Formation of NATO).
The entente alliances follow a similar pattern where the alliance ended and was immediately reformed. There were a few countries where there was an entente alliance formed towards the end of the Korean War and ended a few years after the end of the Vietnam war. The majority of the countries that follow the described patters are in Asia or Australia. This is reasonable considering they were participants is the Vietnam War. Also, the defense and entente alliance between the US and Cuba ended during the Vietnam War, indicated in the graph above, when Cuba was providing military support to the Vietnamese. Also, during the Vietnam war, there was a neutrality alliance for a few years between the US and countries that participated in the Vietnam war. This alliance was called the International Agreement on the Neutrality of Laos starting in 1961 and was terminated when was Democratic Republic of Vietnam violated the terms of the treaty 2 years later (Vietnam War History).
Conclusions & Next Steps
Since we are mainly focusing on large-scale wars that involved various countries, many treaties were created and broken. For example, Warsaw Pact was created as a counter weight to the NATO Pact created at end of WWII. The US, Great Britain and their allies became part of NATO and the Soviet Union and its Allies became part of the Warsaw pact. Once the USSR dissolved many of the satellite nations, the Warsaw Pact members joined NATO. With NATO and the formation of the United Nations, it is hard to say which countries will participate in the next war. For example, before the beginning of the War on Afghanistan, the security council had to authorize the United States and NATO allies to organize an offensive against al-Qaeda (Witte). This type of regulation makes it hard to determine how future wars will play out. One thing that was interesting is that once a treaty falls apart, the members try to join another treaty which is why we see spikes is the median number of alliances towards the end of the wars.
One of the things that was hard to work with this data set is that it was impossible to tell which alliances were part of a larger treaty. For example, if there was a data point for an alliance between the US and the UK in 1967, there was no indication of if it was NATO or some other treaty. This also made it hard to tell when a country joined an existing alliance. For example, when Germany joined NATO there were data points for an alliance between Germany and the NATO members but it is not easy to discern that Germany join NATO without some internet research.
The other downfall of this data set is that it only considers formal military alliances. It does not consider other types of alliances such as the United Nations & security council or a trade agreement. For example, Japan is not in any military alliance currently but it does have very close ties to the United States today, and this information is not captured in the data set.
Militarized Interstate Disputes
The data is rich and contains many dimensions such as the outcomes, settlements, the number of fatalities, minimum duration, the highest action taken and hostility level during each militarized conflict in the last century. Hence as the first step, we selected a few variables and plotted them in a pcp to try and spot correlations.
library(ggplot2)
library(dplyr)
library(grid)
library(gridExtra)
library(RColorBrewer)
library(GGally)
Attaching package: ‘GGally’
The following object is masked from ‘package:dplyr’:
nasa
#path = "/home/vaguiar/col_hw/vis_hw/final/data/"
MIDA = read.csv(file="./data/MID/MIDA_4.01.csv", sep= ",")
war_year <- function(x){
if(x >= 1914 & x <= 1918)
return('WWI')
if(x >= 1939 & x <= 1945)
return('WWII')
if(x >= 1950 & x <= 1953)
return('Korean War')
if(x >= 1955 & x <= 1975)
return('Vietnam War')
if(x >= 1947 & x <= 1991)
return('Cold War')
if(x >= 2001 & x <= 2010)
return('War in Afghanistan')
else
return('No War')
}
MIDA$wartime <- sapply(MIDA$StYear, war_year)
##PCP PLot
alphabending = 0.5
war <- ggparcoord(MIDA[MIDA$StYear>1900 & MIDA$wartime!='No War',], columns = c(9:11, 14:16),
scale = "uniminmax",
alphaLines = alphabending,
groupColumn = "wartime",
title="Correlations In War Time Conflicts") +
theme_classic() +
theme(legend.position = "bottom")
#guides(fill=guide_legend(title="War Period",
# title.position = "bottom",
# nrow=1))
peace <- ggparcoord(MIDA[MIDA$StYear>1900 & MIDA$wartime=='No War',], columns = c(9:11, 14:16),
scale = "uniminmax",
alphaLines = alphabending,
groupColumn = "wartime",
title="Correlations In Peace Time Conflicts") +
theme_classic() +
theme(legend.position = "bottom")
#guides(fill=guide_legend(title="War Period",
# title.position = "bottom",
# nrow=1))
grid.arrange(war, peace, nrow = 2)

In the graph plotting War Time Correlations, we see that most of the data points for Fatality, Settlement and Outcome gravitate towards the top half. There’s also a high level of correlation between those three. Minimum Duration was partly skewed and the rest were evenly distributed. As for the Peace Time Correlations, the first three variables seem pretty evenly distributed too.
Below, we dig a little deeper into variables like Fatalities, Settlements and Outcomes of the conflicts. Each graph is overlaid with the time period of the major wars. Through this exploration, we try to spot possible predictors of a war.
Fatalaties In Disputes Leading to War
# Overlay w/ rectangle theme
y2_high =9
d = data.frame(x1=c(1914,1939, 1947, 1950, 1955, 2001), x2=c(1918, 1945, 1991, 1953, 1975, 2010), y1=c(0,0,0,0,0,0), y2=c(y2_high,y2_high,y2_high,y2_high,y2_high,y2_high), Conflict=c("WWI", "WWII", "Cold War", "Korean War", "Vietnam War", "Afghanistan War"), r=c(1,2,3,4,5,6))
#Adding Labels for Facet titles
facet_names <- as_labeller(c(
'0' = "None",
'1' = "1-25 deaths",
'2' = "26-100 deaths",
'3' = "101-250 deaths",
'4' = "251-500 deaths",
'5' = "501-999 deaths",
'6' = "More than 999 deaths",
'-9' = "Missing Data"
))
ggplot() +
geom_bar(data=MIDA[MIDA$EndYear>1900 & MIDA$Fatality!=0 & MIDA$Fatality!=-9,], aes(x = EndYear), stat="count") +
facet_wrap(~Fatality, nrow= 8, labeller=facet_names) +
scale_fill_manual(values = myPal) +
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, fill=Conflict), alpha=0.15) +
ggtitle("Number Of Disputes With Fatalities By Year") +
xlab("End Year") +
ylab("Count")

In the graph above we have plotted the Fatalities occurring due to militarized conflicts every year since the year 1900. We’ve faceted the graphs by the number of fatalities starting from 1-25, 25-100, 101-250 and so on. Within each facet, the data is mildly interspersed with a larger concentration during the war years and sparse distribution at other times. But, interestingly so, there were conflicts resulting in more than 999 deaths in the years leading to the each and every major war. And in four of those years, namely 1913, 1938, 1955, and 2001, we see spikes in the number of deaths. This could be indicative of the fact that those conflicts forced an international involvement in the wars.
Settlement of Disputes Leading to War
# Overlay w/ rectangle theme
y2_high = 9
d = data.frame(x1=c(1914,1939, 1947, 1950, 1955, 2001), x2=c(1918, 1945, 1991, 1953, 1975, 2010), y1=c(0,0,0,0,0,0), y2=c(y2_high,y2_high,y2_high,y2_high,y2_high,y2_high), Conflict=c("WWI", "WWII", "Cold War", "Korean War", "Vietnam War", "Afghanistan War"), r=c(1,2,3,4,5,6))
#Adding Labels for Facet titles
facet_names <- as_labeller(c(
'1' = "Negotiated",
'2' = "Imposed",
'3' = "None",
'4' = "Unclear",
'-9' = "Missing Data"
))
ggplot() +
geom_bar(data=MIDA[MIDA$EndYear>1900 & MIDA$Settle!=3 & MIDA$Settle!='-9', ], aes(x = EndYear), stat="count") +
facet_wrap(~Settle, nrow= 5, labeller=facet_names) +
scale_fill_manual(values = myPal) +
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, fill=Conflict), alpha=0.15) +
ggtitle("Number Of Disputes With Settlement Outcomes By Year") +
xlab("End Year") +
ylab("Count")

In the graph above we have plotted the Settlement outcomes of different militarized conflicts every year since the year 1900. We’ve faceted the graphs by the Settlement types and for simplicity we’ve left out missing data or settlements that were unclear.
Surprisingly, we don’t see any correlations between Imposed/Negotiated Settlements and the war. But on second thought, the number of Settlements, would not be an important predictor of war. This could be due to the fact that some Settlements, such as such as the Treaty of Versailles [Treaty of Versailles] which was punitive and complex in nature, had a major role in shaping the political climate of Nazi Germany. But since the data doesn’t delve into the qualitative aspects of these Settlements and it is of little or no significance to our exploration.
Outcomes of Disputes Leading to War
# Overlay w/ rectangle theme
y2_high =65
d = data.frame(x1=c(1914,1939, 1947, 1950, 1955, 2001), x2=c(1918, 1945, 1991, 1953, 1975, 2010), y1=c(0,0,0,0,0,0), y2=c(y2_high,y2_high,y2_high,y2_high,y2_high,y2_high), Conflict=c("WWI", "WWII", "Cold War", "Korean War", "Vietnam War", "Afghanistan War"), r=c(1,2,3,4,5,6))
MIDA_o <- filter(MIDA, MIDA$Outcome %in% c(1,2,3,4,5,6,8,-9))
war_outcome <- function(x){
if(x ==2)
return(1)
if(x == 4)
return(3)
else
return(x)
}
MIDA_o$WarOutcome <- sapply(MIDA_o$Outcome, war_outcome)
#Adding Labels for Facet titles
facet_names <- as_labeller(c(
'1' = "Victory For Either Side",
'3' = "Yield By Either Side",
'5' = "Stalemate",
'6' = "Compromise",
'8' = "Unclear",
'-9' = "Missing Data"
))
ggplot() +
geom_bar(data=MIDA_o[MIDA_o$EndYear>1900 & MIDA_o$WarOutcome!='-9' , ],
aes(x = EndYear), stat="count") +
facet_wrap(~WarOutcome, nrow= 5, labeller=facet_names) +
scale_fill_manual(values = myPal) +
geom_rect(data=d, mapping=aes(xmin=x1, xmax=x2, ymin=y1, ymax=y2, fill=Conflict), alpha=0.15) +
ggtitle("Number Of Disputes With Outcomes By Year") +
xlab("End Year") +
ylab("Count")

In the graph above we have plotted the Outcomes of different militarized conflicts every year since the year 1900. We’ve faceted the graphs by the Outcomes and for simplicity, we’ve left out missing data or outcomes that were unclear. There is little evidence to show that certain types Outcomes were predictive of a war. But surprisingly so, we see that Stalemates peaked during the middle of an ongoing war. We see that in WWII, the Vietnam War and during War in Afghanistan. On further analysis, the years that correspond to the spike in stalemates in WW2 and the Vietnam War were the exact years in which the US entered both those wars; namely 1942 [The United States Declares War on Japan] and 1964 [Gulf of Tonkin Resolution]. The introduction of a major military power could explain the shift in the power.
Conclusions & Next Steps
The face of modern warfare has changed dramatically in the past few decades. With technological advancements, militaries now resort to elite electronic warfare which enables them to target their enemies without any human presence on site. Cyber war is also widely employed to conduct espionage or to influence biases in the world. Countries maintain huge arsenals of strategic defense weapons such as Intercontinental Ballistic Missiles [ICBM] and Ballistic Missile Nuclear Submarines [SSBN] to serve as important deterrents to international conflicts. And learning from the past ravages of war, many countries stand united in collectively punishing rogue nations through trade embargoes or economic maneuvers. With such a shift in military strategy, the MID data may contain newer dimensions in the future. The involvement of certain actors may be harder to prove or pin point and the existing variables may not serve as valid predictors of an imminent war.
But for the next steps of this exploration, we could work to consider the interplay of trade and economic reliance on the peace between borders. Through the MIDB data set we could drill down into the individual disputes between countries and their occurrences over time. Superimpose that over economic or trading ties during the same time periods, or the forming of other international alliances and we could have valuable findings.
Sources
“About the Correlates of War Project.” Correlates of War. N.p., 05 Apr. 2014. Web. 19 Apr. 2017.
“Battlefield: Vietnam.” PBS. Public Broadcasting Service, n.d. Web. 19 Apr. 2017.
“Cold War.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., n.d. Web. 19 Apr. 2017.
Formal Alliances (v4.1). Gibler, Douglas M. 2009. International military alliances, 1648-2008. CQ Press.
“Formation of NATO.” History.com. A&E Television Networks, 2010. Web. 19 Apr. 2017.
“Gulf of Tonkin Resolution.” Wikipedia. Wikimedia Foundation, 18 Apr. 2017. Web. 19 Apr. 2017.
“ICBM - Intercontinental Ballistic Missile.” Wikipedia. Wikimedia Foundation, 19 Apr. 2017. Web. 20 Apr. 2017.
Jones, Daniel M., Stuart A. Bremer and J. David Singer. 1996 .“Militarized Interstate Disputes, 1816-1992: Rationale, Coding Rules, and Empirical Patterns.” Conflict Management and Peace Science 15:163-213.
National Material Capabilities (v5.0). Singer, J. David, Stuart Bremer, and John Stuckey. (1972). “Capability Distribution, Uncertainty, and Major Power War, 1820-1965.” in Bruce Russett (ed) Peace, War, and Numbers, Beverly Hills: Sage, 19-48.
Palmer, Glenn, Vito D’Orazio, Michael Kenwick, and Matthew Lane. 2015. “The MID4 Data Set: Procedures, Coding Rules, and Description.” Conflict Management and Peace Science. Forthcoming.
“Persian Gulf War.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., n.d. Web. 19 Apr. 2017.
“The Rio Pact at a Glance.” The New York Times. The New York Times, 20 Apr. 1982. Web. 19 Apr. 2017.
Royde-Smith, John Graham. “World War I.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., 09 Dec. 2016. Web. 19 Apr. 2017.
Royde-Smith, John Graham. “World War II.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., 03 Feb. 2017. Web. 19 Apr. 2017.
“SSBN - Ballistic Missile Submarine.” Wikipedia. Wikimedia Foundation, 08 Apr. 2017. Web. 20 Apr. 2017.
“The United States Declares War on Japan.” History.com. A&E Television Networks, n.d. Web. 19 Apr. 2017.
“Vietnam War History.” History.com. A&E Television Networks, 2009. Web. 19 Apr. 2017.
Witte, Griff. “Afghanistan War.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., 14 Oct. 2016. Web. 19 Apr. 2017.
“Treaty of Versailles.” Encyclopædia Britannica. Encyclopædia Britannica, Inc., n.d. Web. 19 Apr. 2017.
LS0tCnRpdGxlOiAiVGFsZSBvZiBXYXIiCm91dHB1dDogaHRtbF9ub3RlYm9vawphdXRob3I6ICJDeW50aGlhIENsZW1lbnQgJiBWaW5lZXQgQWd1aWFyIgotLS0KYGBge3IsIGVjaG8gPSBGQUxTRX0KCiMjIExvYWQgUGFja2FnZXMgCgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3JpZCkKbGlicmFyeShncmlkRXh0cmEpCmxpYnJhcnkodGlkeXIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodmlyaWRpcykKbGlicmFyeShndG9vbHMpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQoKCiMjaW1wb3J0IGRhdGEKCiNOTUMKCk5NQ19vcmlnID0gcmVhZC5jc3YoIi4vZGF0YS9OTUNfNV8wL05NQ181XzAuY3N2Iiwgc2VwPSAiLCIpCgojQWxsaWFuY2VzIApkeWFkX2FsXzA9IHJlYWQuY3N2KCIuL2RhdGEvdmVyc2lvbjQuMV9jc3YvYWxsaWFuY2VfdjQuMV9ieV9keWFkLmNzdiIsIHNlcD0gIiwiKQpkeWFkX2FsX3llYXIgPSByZWFkLmNzdigiLi9kYXRhL3ZlcnNpb240LjFfY3N2L2FsbGlhbmNlX3Y0LjFfYnlfZHlhZF95ZWFybHkuY3N2Iiwgc2VwPSAiLCIpCgptZW1iZXJfYWxsaWFuY2VzID0gcmVhZC5jc3YoIi4vZGF0YS92ZXJzaW9uNC4xX2Nzdi9hbGxpYW5jZV92NC4xX2J5X21lbWJlci5jc3YiLCBzZXA9ICIsIikKbWVtYmVyX2FsX3llYXIgPSByZWFkLmNzdigiLi9kYXRhL3ZlcnNpb240LjFfY3N2L2FsbGlhbmNlX3Y0LjFfYnlfbWVtYmVyX3llYXJseS5jc3YiLCBzZXA9ICIsIikKCmRpcl9hbF95ZWFyPSByZWFkLmNzdigiLi9kYXRhL3ZlcnNpb240LjFfY3N2L2FsbGlhbmNlX3Y0LjFfYnlfZGlyZWN0ZWRfeWVhcmx5LmNzdiIsIHNlcD0gIiwiKQpkaXJfYWw9IHJlYWQuY3N2KCIuL2RhdGEvdmVyc2lvbjQuMV9jc3YvYWxsaWFuY2VfdjQuMV9ieV9kaXJlY3RlZC5jc3YiLCBzZXA9ICIsIikKCiMjIEV2ZW50cyBEYXRhIEZyYW1lIAoKZD1kYXRhLmZyYW1lKHgxPWMoMTkxNCwxOTM5LCAxOTQ3LCAxOTUwLCAxOTU1LCAyMDAxKSwgeDI9YygxOTE4LCAxOTQ1LCAxOTkxLCAxOTUzLCAxOTc1LCAyMDEwKSwgQ29uZmxpY3Q9YygiV1dJIiwgIldXSUkiLCAiQ29sZCBXYXIiLCAiS29yZWFuIFdhciIsICJWaWV0bmFtIFdhciIsICJBZmdoYW5pc3RhbiBXYXIiKSwgcj1jKDEsMiwzLDQsNSw2KSkKCm15bGFibGVzIDwtIGMoIk5vIFdhciIgLCAiV1dJIiwgIldXSUkiLCAiQ29sZCBXYXIiLCAiS29yZWFuIFdhciIsICJWaWV0bmFtIFdhciIsICJBZmdoYW5pc3RhbiBXYXIiKQpgYGAKCgojI0ludHJvZHVjdGlvbgoKV2FycyBhcmUgY29tcGxleCBldmVudHMgYm9ybiBvZiBnZW9wb2xpdGljYWwsIGN1bHR1cmFsIG9yIGVjb25vbWljIHN0cmlmZSwgb2Z0ZW4gc3Bhbm5pbmcgbWFueSB5ZWFycyBidXQgdWx0aW1hdGVseSBjb3N0aW5nIGxpdmVzLCBsaXZlbGlob29kIGFuZCBwZWFjZS4gRHVyaW5nIHdhcnMsIGNvdW50cmllcyBxdWlja2x5IGFkb3B0IGlkZW9sb2dpZXMsIGZvcm0gYWxsZWdpYW5jZXMsIGFuZCBkaXNjaXBsaW5lIHRoZWlyIGVjb25vbWljIGFuZCBzY2llbnRpZmljIHByaW9yaXRpZXMgd2hpbGUgbWFpbnRhaW5pbmcgdGhlaXIgbWlsaXRhcnkgZm9jdXMgd2l0aCBhIGJsaW5kIGFkaGVyZW5jZS4gQWx0aG91Z2ggdGhlIGNhdXNlcyBvZiB0aGlzIGRpc3BsYWNlbWVudCBvZiBwZWFjZSBtYXkgdmFyeSwgaXMgdGhlcmUgYSBwcmVjdXJzb3J5IHBhdHRlcm4gdG8gaXQ/IERvZXMgdGhlIGxhbmRzY2FwZSBjaGFuZ2UgYWZ0ZXIgdGhlIGVuZCBvZiBhIHByb2xvbmdlZCBjb25mbGljdD8gRG8gY2VydGFpbiBhY3RvcnMgYmVuZWZpdCBtb3JlPyBEbyBzb21lIGxvc2UgbW9yZSB0aGFuIG90aGVycz8gQW5kIG1vc3QgaW1wb3J0YW50bHksIGNvdWxkIHRoZXJlIGJlIGltcG9ydGFudCBwcmVkaWN0b3JzIG9mIHRoZXNlIGVwaWMgZXZlbnRzIHRoYXQgY2hhbmdlIHRoZSBjb3Vyc2Ugb2YgaGlzdG9yeT8gCgpXZSBhcmUgcGFydGljdWxhcmx5IGludGVyZXN0ZWQgaW4gc3R1ZHlpbmcgdGhlIGNoYW5nZXMgdGhhdCBoYXBwZW4gdG8gYSBjb3VudHJ5IGJlZm9yZSBhbmQgYWZ0ZXIgdGhleSBlbnRlciBhIHdhci4gV2Ugd2FudCB0byBzZWUgdGhlIGNoYW5nZSBvZiBhbGxpYW5jZXMgYW5kIHN0cmF0ZWdpZXMsIGl0J3MgaW1wYWN0IG9uIHRyYWRlIGFuZCBjb21tZXJjZSBhbmQgdGhlIGVjb25vbWljcyBhdCBwbGF5LiBXZSBhbHNvIHdhbnQgdG8gY29tcGFyZSBhbmQgY29udHJhc3QgdGhlIGNoYXJhY3RlcmlzdGljcyBvZiBjb3VudHJpZXMgd2hvIHdvbiB3YXJzIHdpdGggdGhlIG9uZXMgdGhhdCBsb3N0LiBPdXIgZXZlbnR1YWwgZ29hbCBpcyB0byBmaW5kIGNlcnRhaW4gZmFjdG9ycyB0aGF0IGluZGljYXRlIHdoaWNoIGNvdW50cmllcyB3aWxsIGVudGVyIGEgd2FyIGFuZCBob3cgdGhlc2UgZmFjdG9ycyBhbmQgcHJlZGljdG9ycyBjaGFuZ2Ugb3ZlciB0aW1lLiAKClRvIGxpbWl0IG91ciBzY29wZSwgd2Ugd2lsbCBleHBsb3JlIHRoZSBkYXRhIHdpdGggYSBwYXJ0aWN1bGFyIGVtcGhhc2lzIG9uIHRoZSBVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EgYW5kIHRoZSB3YXJzIGl0IGhhcyBmb3VnaHQgc2luY2UgMTkwMC4gQXQgdmFyaW91cyBwb2ludHMsIHdlIG1heSBoYXZlIHRvIGluY2x1ZGUgY29tcGFyaXNvbnMgYmV0d2VlbiBjb3VudHJpZXMgYW5kIHRoZSBVUyBhbmQgd2Ugd2lsbCBleHBsb3JlIHRoZSBkYXRhIGJyZWFkdGgtd2lzZSB0byBkcmF3IG1lYW5pbmdmdWwgaW5zaWdodHMuICAKCkZvciBvdXIgdGltZWxpbmUsIHdlIHBsYW4gdG8gbG9vayBhdCBldmVudHMvYWN0aXZpdHkgbGVhZGluZyB0bywgZHVyaW5nIGFuZCBmb2xsb3dpbmcgdGhlIG1ham9yIFVTIHdhcnMsIG5hbWVseTsgIApXV0kgICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gMTkxNC0xOTE4ICAKV1dJSSAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAxOTM5LTE5NDUgIApDb2xkIFdhciAtLS0tLS0tLS0tLS0tLS0tLS0tLSAxOTQ3LTE5OTEgIApLb3JlYW4gV2FyIC0tLS0tLS0tLS0tLS0tLS0gMTk1MC0xOTUzICAKVmlldG5hbSBXYXIgLS0tLS0tLS0tLS0tLS0tIDE5NTUtMTk3NSAgCldhciBpbiBBZmdoYW5pc3RhbiAtLS0tLS0tIDIwMDEtMjAxMCAKCkFsdGhvdWdoIHRoZSBDb2xkIFdhciB3YXMgb25seSBhIHN0YXRlIG9mIHNldmVyZSBwb2xpdGljYWwgdGVuc2lvbiBiZXR3ZWVuIHRoZSBFYXN0ZXJuIEJsb2MgYW5kIFdlc3Rlcm4gQmxvYyB0aGVyZSB3ZXJlIG1hbnkgcmVnaW9uYWwgYmF0dGxlcyBhbmQgdGhlIHRocmVhdCBvZiBhIGxhcmdlLXNjYWxlIG1pbGl0YXJ5IHdhciB3YXMgY29uc3RhbnQuIFdlIGNob3NlIHRvIGluY2x1ZGUgdGhlIENvbGQgV2FyIGluIG91ciBhbmFseXNpcyB0byBzZWUgaWYgdGhlcmUgd2VyZSBhbnkgZGlmZmVyZW5jZXMgZm9yIGEgdGhyZWF0IG9mIHdhciBjb21wYXJlZCB0byBhbiBhY3R1YWwgd2FyLiAKCgojIyBUaGUgRGF0YSwgVGVhbSBNZW1iZXJzIGFuZCBUaGUgUm9sZXMKClRoZSBbQ29ycmVsYXRlcyBvZiBXYXIgUHJvamVjdF0oaHR0cDovL3d3dy5jb3JyZWxhdGVzb2Z3YXIub3JnKSBpcyBhIHRyZWFzdXJlIHRyb3ZlIG9mIGluZm9ybWF0aW9uLiBXZSBoYXZlIGEgc3BlY2lhbCBpbnRlcmVzdCBpbiB0aGUgZm9sbG93aW5nIGRhdGFzZXRzOiBUcmFkZSwgTmF0aW9uYWwgTWF0ZXJpYWxzIENhcGFiaWxpdGllcyAoTk1DKSwgQWxsaWFuY2VzIGFuZCBNaWxpdGFyaXplZCBJbnRlcnN0YXRlIERpc3B1dGVzIChNSUQpCgoqKk91ciBQbGFuKiogIApXZSd2ZSBkZWNpZGVkIHRvIGRpdmlkZSBhbmQgY29ucXVlciB0aGUgd29yayBieSBlYWNoIHRha2luZyBhIHN1YnNldCBvZiB0aGUgZGF0YSBhbmQgZXhwbG9yaW5nIGl0LiBBZnRlciBzb21ldGltZSwgd2Ugd2lsbCByZWdyb3VwIHRvIHNlZSB3aGF0IHdlJ3ZlIGxlYXJudCBzbyBmYXIgYW5kIHN3aXRjaCBkYXRhIHNldHMgYW1vbmdzdCBvdXJzZWx2ZXMgdG8gc2VlIGlmIHRoZXJlIGFyZSBtb3JlIGluc2lnaHRzIHRvIGJlIGxlYXJudCBvciBkaWZmZXJlbnQgYXBwcm9hY2hlcyB0byB2aXN1YWxpemUgdGhlIGV4aXN0aW5nIGRhdGEuIExhc3RseSwgd2Ugd2FudCB0byBkcmlsbCBkb3duIGludG8gcGFydGljdWxhciB2YXJpYWJsZXMgYW5kIHBsb3QgY29ycmVsYXRpb25zIG9yIHByZWRpY3RvcnMgZm9yIHRoZSBmaW5hbCBvdXRwdXQuCgoqUGhhc2UgMToqICAKKiBDeW50aGlhIHRvIGFuYWx5emUgTmF0aW9uYWwgTWF0ZXJpYWxzIENhcGFiaWxpdGllcyBhbmQgQWxsaWFuY2VzICAKKiBWaW5lZXQgdG8gYW5hbHl6ZSBNaWxpdGFyaXplZCBJbnRlcnN0YXRlIERpc3B1dGVzIGFuZCBUcmFkZSAgCgoqUGhhc2UgMjoqICAKKiBXZSBhcmUgZ29pbmcgdG8gc3dpdGNoIHRoZSBkYXRhIHNldHMgd2UgYXJlIGxvb2tpbmcgYXQgdG8gc2VlIGlmIHRoZSBvdGhlciBwZXJzb24gY2FuIGRpc2Nlcm4gYW55IG5ldyBpbnNpZ2h0cyBvciBjcmVhdGl2ZSB3YXlzIG9mIHByZXNlbnRpbmcgdGhlIGRhdGEuICAKICArIEN5bnRoaWEgdG8gYW5hbHl6ZSBNaWxpdGFyaXplZCBJbnRlcnN0YXRlIERpc3B1dGVzIGFuZCBUcmFkZSAgCiAgKyBWaW5lZXQgdG8gYW5hbHl6ZSBOYXRpb25hbCBNYXRlcmlhbHMgQ2FwYWJpbGl0aWVzIGFuZCBBbGxpYW5jZXMgICAKCgojIyBBbmFseXNpcyBvZiBEYXRhIFF1YWxpdHkgCgpUaGUgQ29ycmVsYXRlcyBvZiBXYXIgZGF0YXNldHMgYXJlIGEgcHJvZHVjdCBvZiB0aGUgQ29ycmVsYXRlIG9mIFdhciBQcm9qZWN0IChDT1cpIGZvdW5kZWQgaW4gMTk2My4gQ09XJ3MgZ29hbCBpcyB0byAiZmFjaWxpdGF0ZSB0aGUgY29sbGVjdGlvbiwgZGlzc2VtaW5hdGlvbiwgYW5kIHVzZSBvZiBhY2N1cmF0ZSBhbmQgcmVsaWFibGUgcXVhbnRpdGF0aXZlIGRhdGEgaW4gaW50ZXJuYXRpb25hbCByZWxhdGlvbnMuIiBbQ29ycmVsYXRlcyBvZiBXYXIgUHJvamVjdF0gRnJvbSB0aGUgQ09XIGRhdGFzZXRzIHdlIGZvY3VzZWQgb24gNCBkYXRhc2V0czogTmF0aW9uYWwgTWF0ZXJpYWxzIENhcGFiaWxpdGllcywgTWlsaXRhcml6ZWQgSW50ZXJzdGF0ZSBEaXNwdXRlcywgQWxsaWFuY2VzIGFuZCBUcmFkZS4gQXMgdGhlc2UgZGF0YSBzZXRzIGFyZSBwYXJ0IG9mIHRoZSBDT1cgcHJvamVjdCwgdGhlIGF1dGhvcml0eSwgYWNjdXJhY3kgYW5kIG9iamVjdGl2aXR5IG9mIHRoZSBkYXRhIHNldHMgYXJlIGltcGVjY2FibGUuIEFsbCB0aGUgZGF0YSBzZXRzIHVzZSBhIGZpZWxkIGNhbGxlZCBjb3VudHJ5IGNvZGUsIGEgbnVtZXJpYyBJRCBnaXZlbiB0byBlYWNoIGNvdW50cnkuIFRoaXMgaXMgYSBjb25zaXN0ZW50IGZpZWxkIHRoYXQgY2FuIGJlIHVzZWQgdG8gdGllIHRoZSBkYXRhIGFjcm9zcyB0aGUgZGF0YSBzZXRzIGluIHRoZSBDT1cgcHJvamVjdC4gCgoqKk5hdGlvbmFsIE1hdGVyaWFscyBDYXBhYmlsaXRpZXMqKgogIApUaGUgb3ZlcmFsbCBkYXRhIHF1YWxpdHkgb2YgTk1DIGRhdGFzZXQgaXMgdmVyeSBnb29kLiBUaGVyZSBhcmUgcm91Z2hseSAxNCwwMDAgZW50cmllcyBhbmQgODklIG9mIHRoZW0gZGlkIG5vdCBoYXZlIGFueSBtaXNzaW5nIHZhbHVlcy4gVGhlcmUgaXMgb25lIGRhdGEgZW50cnkgZm9yIGVhY2ggY291bnRyeSBwZXIgeWVhci4gVGhlIGFjY3VyYWN5IG9mIHRoZSBkYXRhIGlzIGFsc28gdmVyeSBnb29kIGJlY2F1c2UgYXMgY291bnRyaWVzIGFyZSBkaXNzb2x2ZWQgYW5kIG5ldyBvbmVzIGFyZSBmb3JtZWQsIHRoaXMgZGF0YSBrZWVwcyB0cmFjayBvZiB0aGVtLiBGb3IgZXhhbXBsZSwgdGhlIGdyYXBoIGRlcGljdHMgdGhlIENJTkMgb2YgQXVzdHJpYS1IdW5nYXJ5IGZyb20gMTkwMC0xOTE4LCB0aGUgZW5kIG9mIFdXSSB3aGVuIGl0IHRoZSBBdXN0cm8tSHVuZ2FyaWFuIEVtcGlyZSB3YXMgZGlzc29sdmVkLiBJbW1lZGlhdGVseSBhZnRlciB0aGF0LCB5b3Ugc2VlIGRhdGEgcG9pbnRzIGZvciBBdXN0cmlhIGFuZCBIdW5nYXJ5IHNlcGFyYXRlbHkuIFRoaXMgc2FtZSBhY2N1cmFjeSBob2xkIHRydWUgZm9yIG1hbnkgZGlmZmVyZW50IGNvdW50cmllcywgd2hlcmUgdGhlcmUgaXMgb25seSBkYXRhIG9uY2UgdGhlIGNvdW50cnkgaGFzIGRlY2xhcmVkIGluZGVwZW5kZW5jZSBvciBoYXMganVzdCBiZWVuIGNyZWF0ZWQuIAoKYGBge3IgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTV9Ck5NQ190ZXN0IDwtIE5NQ19vcmlnCk5NQ190ZXN0JGNpbmNbTk1DX3Rlc3QkY2luYyA9PSAtOV0gPC0gTkEKTk1DX3Rlc3QkaXJzdFtOTUNfdGVzdCRpcnN0ID09IC05XSA8LSBOQQpOTUNfdGVzdCRtaWxleFtOTUNfdGVzdCRtaWxleCA9PSAtOV0gPC0gTkEKTk1DX3Rlc3QkbWlscGVyW05NQ190ZXN0JG1pbHBlcj09IC05XSA8LSBOQQpOTUNfdGVzdCRwZWNbTk1DX3Rlc3QkcGVjID09IC05XSA8LSBOQQpOTUNfdGVzdCR0cG9wW05NQ190ZXN0JHRwb3AgPT0gLTldIDwtIE5BCk5NQ190ZXN0JHVwb3BbTk1DX3Rlc3QkdXBvcCA9PSAtOV0gPC0gTkEKCk5NQ190ZXN0IDwtIGZpbHRlcihOTUNfdGVzdCwgTk1DX3Rlc3QkeWVhciAlaW4lIGMoMTkwMDoyMDA3KSkKdGVzdCA8LSBjKCJBdXN0cmlhLUh1bmdhcnkiLCAiQXVzdHJpYSIsICJIdW5nYXJ5IikKdGVzdF9jY29kZSA8LSBtZW1iZXJfYWxsaWFuY2VzJGNjb2RlW21hdGNoKHRlc3QsIG1lbWJlcl9hbGxpYW5jZXMkc3RhdGVfbmFtZSldCgpOTUNfdGVzdCA8LSBmaWx0ZXIoTk1DX3Rlc3QsIE5NQ190ZXN0JGNjb2RlICVpbiUgdGVzdF9jY29kZSkKCmdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJDSU5DIikgKwogIGxhYnMoY29sb3IgPSdDb3VudHJ5IEFiYnJldmlhdGlvbicpKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD0uMDksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ190ZXN0LCBhZXMoeCA9IHllYXIsIHkgPSBjaW5jLCBjb2xvciA9IHN0YXRlYWJiLCBncm91cCA9IHN0YXRlYWJiKSkgKwogIGdndGl0bGUoIkNJTkMgZm9yIEF1c3RyaWEtSHVuZ2FyeSIpICsgCiAgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSAKCmBgYAogIApCZWxvdyBpcyBoZWF0IG1hcCBvZiBDSU5DIHZhbHVlcyBmb3IgYSBmZXcgY291bnRyaWVzIGFuZCB3ZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIG1pc3NpbmcgQ0lOQyB2YWx1ZXMgZm9yIGNlcnRhaW4gY291bnRyaWVzLiBNb3JlIHNwZWNpZmljYWxseSwgdGhpcyB0aGUgaGVhdCBtYXAgYmVsb3cgc2hvd3MgdGhlIENJTkMgdmFsdWVzIG9mIGNvdW50cmllcyB0aGF0IHdlcmUgZGVzdHJveWVkIGJ5IGJvdGggdGhlIEhvbG9jYXVzdCBhbmQgdGhlIGZpZ2h0IGZvciBmcmVlZG9tIGZyb20gQ29tbXVuaXNtLiBUaGVzZSBjb3VudHJpZXMgaGFkIHRvIGdvIHRocm91Z2ggYSBwZXJpb2Qgb2YgbWFqb3IgcmVmb3JtYXRpb24gYW5kIHJlY292ZXJ5LiBJbiB0aGUgZGF0YSBzZXQsIGFueXRpbWUgdGhhdCBhIGNvdW50cnkgaGFzIGJlZW4gZGV2YXN0YXRlZCBpdCBoYXMgbWlzc2luZyBDSU5DIHZhbHVlcy4gIAoKCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CnRvcENhcyA8LSBjKCJOZXRoZXJsYW5kcyIsICJZdWdvc2xhdmlhIiwgIkxpdGh1YW5pYSIsICJQb2xhbmQiLCAiQXVzdHJpYSIsICJIdW5nYXJ5IiwgIlJvbWFuaWEiLCAiRXN0b25pYSIsICJMdXhlbWJvdXJnIikKdG9wQ2FzX2Njb2RlIDwtIG1lbWJlcl9hbGxpYW5jZXMkY2NvZGVbbWF0Y2godG9wQ2FzLCBtZW1iZXJfYWxsaWFuY2VzJHN0YXRlX25hbWUpXQoKCk5NQ19jYXMgPC0gZmlsdGVyKE5NQ19vcmlnLCBOTUNfb3JpZyR5ZWFyICVpbiUgYygxOTAwOjIwMTIpKQpOTUNfY2FzIDwtIGZpbHRlcihOTUNfY2FzLCBOTUNfY2FzJGNjb2RlICVpbiUgdG9wQ2FzX2Njb2RlKQpmb3IoIGkgaW4gYygxOmxlbmd0aCh0b3BDYXNfY2NvZGUpKSl7CiAgTk1DX2NhcyRjb3VudHJ5W05NQ19jYXMkY2NvZGUgPT0gdG9wQ2FzX2Njb2RlW2ldXSA8LSB0b3BDYXNbaV0KfQoKZ2dwbG90KE5NQ19jYXMsIGFlcyhjb3VudHJ5LCB5ZWFyLCBmaWxsID0gY2luYykpICsgZ2VvbV90aWxlKCkrCiAgeGxhYigiQ291bnRyeSIpICsKICB5bGFiKCJZZWFyIikgKwogIHNjYWxlX2ZpbGxfdmlyaWRpcygpICsgCiAgZ2d0aXRsZSgiQ0lOQyBIZWF0bWFwIGZvciBDb3VudHJpZXMgd2l0aCB0aGUgbW9zdCBIb2xvY2F1c3QgQ2FzdWFsdGllcyIpICsgCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSArCiAgY29vcmRfZmxpcCgpICsKICBsYWJzKGNvbG9yID0nQ0lOQycpCiAgCgpgYGAKCgoqKkFsbGlhbmNlcyoqCgoKVGhlcmUgYXJlIDYgaXRlcmF0aW9ucyBvZiB0aGUgc2FtZSBkYXRhLCBlYWNoIHNlcnZpbmcgYSBkaWZmZXJlbnQgcHVycG9zZS4gVGhlIEFsbGlhbmNlcyBjb250YWlucyB0aGUgYWxsaWFuY2UgZGF0YXNldCBkaXN0cmlidXRlZCBieSBtZW1iZXIsIHdpdGggb25lIG9ic2VydmF0aW9uIGZvciBlYWNoIGFsbGlhbmNlIG1lbWJlciBpbml0aWF0aW9uLiBUaGVyZSBpcyBhbHNvIGFub3RoZXIgZmlsZSB3aXRoIHNhbWUgZGF0YSBidXQgaW5jbHVkZXMgYW4gYWRkaXRpb25hbCBmaWVsZCB0aGF0IGhhcyBhbiBvYnNlcnZhdGlvbiBmb3IgZWFjaCB5ZWFyIHRoZSBtZW1iZXIgaXMgaW4gdGhlIGFsbGlhbmNlLiBUaGVyZSBpcyBhbm90aGVyIGRhdGEgc2V0IHdpdGggb25lIG9ic2VydmF0aW9uIGZvciBlYWNoIGR5YWRpYyBhbGxpYW5jZSBpbml0aWF0aW9uLiBUaGlzIGRhdGEgc2V0IGFsc28gbGlzdCB0aGUgZGV0YWlscyBvZiB0aGUgYWxsaWFuY2VzLiBBcyB3aXRoIHRoZSBhbGxpYW5jZXMgZGF0YSBzZXQsIHRoZSBkeWFkaWMgYWxsaWFuY2VzIGRhdGEgc2V0IGNvbnRhaW5zIGFub3RoZXIgZmlsZSB0aGF0IGhhcyBhbiBvYnNlcnZhdGlvbiBmb3IgZWFjaCB5ZWFyIHRoZSBtZW1iZXIgaXMgaW4gdGhlIGFsbGlhbmNlLiBGaW5hbGx5LCB0aGVyZSBpcyB0aGUgZGlyZWN0ZWQgZHlhZCBkYXRhIHNldCB0aGF0IGhhcyAyIG9ic2VydmF0aW9ucyBwZXIgYWxsaWFuY2UsIHdoZXJlIGl0IGRldGFpbHMgdGhlIHRlcm1zIG9mIHRoZSBhbGxpYW5jZSBvZiBjb3VudHJ5IEEgdG93YXJkcyBjb3VudHJ5IEIsIHRoZW4gYW5vdGhlciBwb2ludCB0byBkZXRhaWxzIHRoZSB0ZXJtcyBvZiBhZ3JlZW1lbnQgb2YgY291bnRyeSBCIHRvd2FyZHMgY291bnRyeSBBLiBBcyB3aXRoIHRoZSBvdGhlciBhbGxpYW5jZXMgZGF0YSBzZXRzLCB0aGVyZSBpcyBhbm90aGVyIGRpcmVjdGVkIGR5YWQgZGF0YSBzZXQgd2l0aCBvbmUgb2JzZXJ2YXRpb24gZm9yIGVhY2ggeWVhciB0aGUgYWxsaWFuY2UgaXMgaW4gZWZmZWN0LiBGcm9tIGFsbCB0aGUgZGF0YSB3ZSBoYXZlIGxvb2tlZCBhdCBpdCBpbiBvdXIgYW5hbHlzaXMsIHRoZSBkYXRhIHNob3dzIGluZm9ybWF0aW9uIHRoYXQgaXMgaW4gbGluZSB3aXRoIGhpc3RvcmljYWwgZXZlbnRzLiAKClNvbWUgb2YgdGhlIGluY29uc2lzdGVuY2llcyB0aGF0IEkgbm90aWNlZCBhcmUgaW4gY2FzZXMgd2hlcmUgdGhlIGFsbGlhbmNlIGlzIHN0aWxsIGluIGVmZmVjdCBhcyBvZiB0aGUgMTIvMzEvMjAxMiwgd2hpY2ggd2FzIHdoZW4gdGhpcyBkYXRhIHNldCB3YXMgbGFzdCB1cGRhdGVkLiBJbiBzb21lIG9mIHRoZSBkYXRhc2V0cywgaWYgdGhlIGFsbGlhbmNlIGlzIG9uZ29pbmcsIGl0IHdvdWxkIGhhdmUgdGhlIGR5YWRfZW5kX3llYXIsIHRoZSBmaWVsZCB0aGF0IHJlcHJlc2VudHMgdGhlIHllYXIgaW4gd2hpY2ggdGhlIGFsbGlhbmNlIHdhcyB0ZXJtaW5hdGVkLCBzZXQgdG8gMjAxMiBhbmQgaW4gb3RoZXIgZGF0YSBzZXRzIGl0IHdvdWxkIGhhdmUgaXQgc2V0IGFzIOKAmE5B4oCZLiBJbiB0aGUgY2FzZSB0aGF0IGR5YWRfZW5kX3llYXIgaXMgc2V0IHRvIDIwMTIsIGl0IHdhcyBoYXJkIHRvIGtub3cgaWYgdGhlcmUgd2VyZSBhbnkgYWxsaWFuY2VzIHRoYXQgZW5kZWQgaW4gMjAxMiBvciBpZiB0aGV5IHdlcmUgYW4gb25nb2luZyBhbGxpYW5jZS4KCgoqKk1pbGl0YXJpemVkIEludGVyc3RhdGUgRGlzcHV0ZXMgKE1JRCkqKiAKClRoZSBNSUQgZGF0YSBpcyB0aG9yb3VnaCBhbmQgd2VsbCBjb2xsYXRlZC4gQXMgY29uZmxpY3RzIG9yIHdhcnMgY2FuIGhhdmUgbXVsdGlwbGUgZGltZW5zaW9ucyB0byB0aGVtLCB0aGUgTUlEIGRhdGEgaXMgYnJva2VuIGRvd24gaW50byAyIG1haW4gZGF0YSBzZXRzLiBNSURBIGNvbnRhaW5zIGFuIG9ic2VydmF0aW9uIHBlciBjb25mbGljdCB3aXRoIGRldGFpbHMgYWJvdXQgdGhlIHN0YXJ0IGFuZCBlbmQgb2YgdGhlIGNvbmZsaWN0LCB0aGUgZmF0YWxpdGllcywgdGhlIG91dGNvbWVzLCB0aGUgc2V0dGxlbWVudHMsIHRoZSBoaWdoZXN0IGFjdGlvbiB0YWtlbiBldGMuIFRoZSBvdGhlciBwYXJ0IG9mIHRoZSBkYXRhc2V0LSBNSURCLCBjb250YWlucyBvbmUgb2JzZXJ2YXRpb24gcGVyIGFjdG9yIGluIGEgY29uZmxpY3QsIHRodXMgYWRkaW5nIGEgZGlmZmVyZW50IGRpbWVuc2lvbiB0byB0aGUgZGF0YS4KCgpgYGB7ciBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9NiwgZWNobyA9IEZBTFNFfQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ3JpZEV4dHJhKQoKTUlEQSA9IHJlYWQuY3N2KGZpbGU9Ii4vZGF0YS9NSUQvTUlEQV80LjAxLmNzdiIsIHNlcD0gIiwiKQoKZmF0YWwgPC0gZ2dwbG90KCkgKyBnZW9tX2hpc3RvZ3JhbShkYXRhID0gTUlEQVtNSURBJEZhdGFsaXR5IT0tOSwgXSwgYWVzKEZhdGFsaXR5KSkgCm91dGNtIDwtIGdncGxvdCgpICsgZ2VvbV9oaXN0b2dyYW0oZGF0YSA9IE1JREFbTUlEQSRPdXRjb21lIT0tOSwgXSwgYWVzKE91dGNvbWUpKQpoaWFjdCA8LSBnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGRhdGEgPSBNSURBW01JREEkSGlBY3QhPS05LCBdLCBhZXMoSGlBY3QpKQpob3N0bCA8LSBnZ3Bsb3QoKSArIGdlb21faGlzdG9ncmFtKGRhdGEgPSBNSURBW01JREEkSG9zdExldiE9LTksIF0sIGFlcyhIb3N0TGV2KSkKICAKZ3JpZC5hcnJhbmdlKGZhdGFsLCBvdXRjbSwgaGlhY3QsIGhvc3RsLCBucm93ID0gMikgIAoKYGBgCkFzIHNlZW4gYWJvdmUsIHRoZSBhdXRob3JzIG9mIHRoZSBkYXRhc2V0IGhhdmUgdXNlZCB0ZWNobmlxdWVzIHRvIGNhdGVnb3JpemUgY2VydGFpbiBzdWJqZWN0aXZlIHZhcmlhYmxlcyBhbmQgdGhlbiBmdXRoZXIgZmFjdG9yIHRoZW0gdG8gdGhlIG51bWJlciBmb3JtYXQuIEZvciBpbnN0YW5jZSwgdGhlICJPdXRjb21lIiBvZiBhIGRpc3B1dGUgd2FzIGZhY3RvcmVkIGFzIGZvbGxvd3MgW1BhbG1lciwgR2xlbm5dOiAgClZpY3RvcnkgZm9yIHNpZGUgQTogMSAgClZpY3RvcnkgZm9yIHNpZGUgQjogMiAgCllpZWxkIGJ5IHNpZGUgQTogMyAgCllpZWxkIGJ5IHNpZGUgQjogNCAgClN0YWxlbWF0ZTogNSAgCkNvbXByb21pc2U6IDYgIApSZWxlYXNlZDogNyAgClVuY2xlYXI6IDggIApKb2lucyBvbmdvaW5nIHdhcjogOSAgCk1pc3Npbmc6IC05ICAKVGhhdCBjcmVhdGVkIGEgY29uZm9ybWl0eSBhbW9uZyBhbGwgcmVjb3JkZWQgb2JlcnZhdGlvbnMgd2hpY2ggbWFkZSBpdCBlYXNpZXIgdG8gd29yayB3aXRoLiAgCkFub3RoZXIgYXJyYW5nZW1lbnQgdGhhdCBtYWRlIHRoZSBkYXRhIGVmZmVjdGl2ZSB3YXMgdGhhdCBjZXJ0YWluIGRhdGFwb2ludHMgd2VyZSBjbGVhcmx5IG1hcmtlZCB1bmNsZWFyIG9yIG1pc3NpbmcgYW5kIGJhc2VkIG9uIHRoZSBjb250ZXh0IG9mIHRoZSBncmFwaCwgd2Ugd2VyZSBhYmxlIHRvIGVhc2lseSBzaWZ0IHRocm91Z2ggdGhlbS4gIAogIAojIyBFeGVjdXRpdmUgU3VtbWFyeSAKICAKKipOYXRpb25hbCBNYXRlcmlhbHMgQ2FwYWJpbGl0aWVzKioKCk5hdGlvbmFsIE1hdGVyaWFscyBDYXBhYmlsaXRpZXMgaXMgbWVhc3VyZSBvZiB0aGUgcG93ZXIgb2YgbmF0aW9uIGJhc2VkIG9uIDYgdmFsdWVzOiBpcm9uIGFuZCBzdGVlbCBwcm9kdWN0aW9uLCBtaWxpdGFyeSBleHBlbmRpdHVyZXMsIG1pbGl0YXJ5IHBlcnNvbm5lbCwgcHJpbWFyeSBlbmVyZ3kgY29uc3VtcHRpb24sIHVyYmFuIHBvcHVsYXRpb24gYW5kIHRvdGFsIHBvcHVsYXRpb24uIEl0IGlzIGFsc28gYSBtZWFzdXJlIG9mIHRoZSBtaWxpdGFyeSBhbmQgZWNvbm9taWMgcG93ZXIgYSBuYXRpb24gY2FuIGhhdmUuIFdlIGFsc28gbG9va2VkIGF0IHRoZSByYXRpb3Mgb2YgdGhlIDYgbWV0cmljcywgY2FsY3VsYXRlZCBieSBzdW1taW5nIHRoZSB0b3RhbCB2YWx1ZXMgb2YgYWxsIGNvdW50cmllcyBmb3IgYSBnaXZlbiB5ZWFyIGFuZCBkaXZpZGluZyB0aGUgdmFsdWUgZm9yIGVhY2ggY291bnRyeSBieSB0aGUgdG90YWwuIFRoZSByYXRpb3MgaGVscGVkIHVzIHRvIG5vcm1hbGl6ZSB0cmVuZHMgdG8gbG9vayBhbmQgaG93IGNvdW50cmllcyBjaGFuZ2UgdGhlaXIgYmVoYXZpb3IsIHJlbGF0aXZlIHRvIG90aGVyIGNvdW50cmllcy4KCgoKYGBge3IsIGVjaG8gPSBGQUxTRX0KY291bnRyaWVzIDwtIGMoIkdlcm1hbnkiKQpjb3VudHJ5X2NvZGUgPC0gbWVtYmVyX2FsbGlhbmNlcyRjY29kZVttYXRjaChjb3VudHJpZXMsIG1lbWJlcl9hbGxpYW5jZXMkc3RhdGVfbmFtZSldCgpOTUMgPC0gTk1DX29yaWcgCk5NQyRjaW5jW05NQyRjaW5jID09IC05fCBpcy5uYShOTUMkY2luYyldIDwtIDAKTk1DJGlyc3RbTk1DJGlyc3QgPT0gLTl8IGlzLm5hKE5NQyRpcnN0KV0gPC0gMApOTUMkbWlsZXhbTk1DJG1pbGV4ID09IC05fCBpcy5uYShOTUMkbWlsZXgpXSA8LSAwCk5NQyRtaWxwZXJbTk1DJG1pbHBlcj09IC05fCBpcy5uYShOTUMkbWlscGVyKV0gPC0gMApOTUMkcGVjW05NQyRwZWMgPT0gLTl8IGlzLm5hKE5NQyRwZWMpXSA8LSAwCk5NQyR0cG9wW05NQyR0cG9wID09IC05fCBpcy5uYShOTUMkdHBvcCldIDwtIDAKTk1DJHVwb3BbTk1DJHVwb3AgPT0gLTl8IGlzLm5hKE5NQyR1cG9wKV0gPC0gMAoKYWxsX3llYXIgPC0gYygxOTAwOjIwMDcpCgpOTUNfcmF0aW9zIDwtIGMoIiIpCmZvciAoeWVhcl90IGluIGFsbF95ZWFyKXsKICB5ciA8LSBmaWx0ZXIoTk1DLCBOTUMkeWVhciAlaW4lIHllYXJfdCkgCiAgbWF4IDwtIGFwcGx5KHlyWywgYyg0OjkpXSwgMiwgc3VtKQogICNtYXggPC0gYXMubnVtZXJpYyhtYXhbNDo5XSkKICBmb3IgKGkgaW4gNDo5KXsKICAgIHlyWyxpXSA9IGFzLm51bWVyaWMoeXJbLGldL21heFtpLTNdKQogIH0KICBOTUNfcmF0aW9zIDwtIHNtYXJ0YmluZChOTUNfcmF0aW9zICwgeXIpCn0KCk5NQ19yYXRpb3MgIDwtIE5NQ19yYXRpb3MgW2MoMjpucm93KE5NQ19yYXRpb3MgKSksIGMoMjpsZW5ndGgoTk1DX3JhdGlvcykpXQoKTk1DX2V4ZWNzdW1fcmF0aW9zIDwtIGZpbHRlcihOTUNfcmF0aW9zLCBOTUNfcmF0aW9zJHllYXIgJWluJSBjKDE5MDA6MTk1MCkpCk5NQ19leGVjc3VtX3JhdGlvcyA8LSBmaWx0ZXIoTk1DX2V4ZWNzdW1fcmF0aW9zLCBOTUNfZXhlY3N1bV9yYXRpb3MkY2NvZGUgJWluJSBjb3VudHJ5X2NvZGUpCk5NQ19leGVjc3VtX3JhdGlvcyRjb3VudHJ5ID0gIiIKZm9yKCBpIGluIGMoMTpsZW5ndGgoY291bnRyeV9jb2RlKSkpewogIE5NQ19leGVjc3VtX3JhdGlvcyRjb3VudHJ5W05NQ19leGVjc3VtX3JhdGlvcyRjY29kZSA9PSBjb3VudHJ5X2NvZGVbaV1dIDwtIGNvdW50cmllc1tpXQp9CgpuYW1lcyhOTUNfZXhlY3N1bV9yYXRpb3MpIDwtIGMoInN0YXRlYWJiIiwgImNjb2RlIiAsICAieWVhciIsICAgICAiRXhwZW5kaXR1cmVzIiAgLCAiUGVyc29ubmVsIiwgICAiaXJzdCIgICAsICJwZWMiLCAgICAgICJ0cG9wIiAgLCJ1cG9wIiwgICAgICJjaW5jIiAsICAidmVyc2lvbiIsICAiY291bnRyeSIpCgpkMj1kYXRhLmZyYW1lKHgxPWMoMTkxNCwxOTM5KSwgeDI9YygxOTE4LCAxOTQ1KSwgQ29uZmxpY3Q9YygiV1dJIiwgIldXSUkiKSwgcj1jKDEsMikpCgpOTUNfZXhlY3N1bV9yYXRpb3MgPC0gZ2F0aGVyKE5NQ19leGVjc3VtX3JhdGlvcywgVHlwZSwgUmF0aW8sIEV4cGVuZGl0dXJlczpQZXJzb25uZWwgKQoKTk1DX2V4ZWNzdW1fcmF0aW9zXzEgPC0gZmlsdGVyKE5NQ19leGVjc3VtX3JhdGlvcywgTk1DX2V4ZWNzdW1fcmF0aW9zJHllYXIgJWluJSBjKDE5MTI6MTkxOCkpICAKTk1DX2V4ZWNzdW1fcmF0aW9zXzEkUmVyaW9kIDwtICJSZWFjdGl2ZSBJbnZlc3RtZW50IgpOTUNfZXhlY3N1bV9yYXRpb3NfMiA8LSBmaWx0ZXIoTk1DX2V4ZWNzdW1fcmF0aW9zLCBOTUNfZXhlY3N1bV9yYXRpb3MkeWVhciAlaW4lIGMoMTkzMjoxOTQxKSkgCk5NQ19leGVjc3VtX3JhdGlvc18yJFBlcmlvZDwtICJQcm9hY3RpdmUgSW52ZXN0bWVudCIKCiBnZ3Bsb3QoKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJZZWFyIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZT0iUmF0aW8iKSArCiAgZ2VvbV9yZWN0KGRhdGE9ZDIsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD0uNSwgZmlsbD1Db25mbGljdCksYWxwaGE9MC4yKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfZXhlY3N1bV9yYXRpb3MsIGFlcyh4ID0geWVhciwgeSA9IFJhdGlvKSwgc2l6ZSA9IC41KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfZXhlY3N1bV9yYXRpb3NfMSwgYWVzKHggPSB5ZWFyLCB5ID0gUmF0aW8pLCBzaXplID0gLjUsIGNvbG9yID0gInBhbGVncmVlbjMiKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfZXhlY3N1bV9yYXRpb3NfMiwgYWVzKHggPSB5ZWFyLCB5ID0gUmF0aW8pLCBzaXplID0gLjUsIGNvbG9yID0gIm9yYW5nZXJlZDIiKSArCiAgZ2d0aXRsZSgiR2VybWFueTogTWlsaXRhcnkgSW52ZXN0bWVudCBSYXRpb3MiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikgKyBmYWNldF93cmFwKH5UeXBlKQoKCmBgYAoKQWJvdmUgaXMgYSBncmFwaCBvZiBHZXJtYW554oCZcyBtaWxpdGFyeSBleHBlbmRpdHVyZXMgcmF0aW8gYW5kIG1pbGl0YXJ5IHBlcnNvbm5lbCByYXRpbyBmcm9tIHRoZSAxOTAwIHRvIDE5NTAuIFdlIGZvdW5kIGlzIHRoYXQgdGhlIG1pbGl0YXJ5IGludmVzdG1lbnQgb2YgYSBjb3VudHJ5IHRoYXQgaW5zdGlnYXRlcyBhIGNvbmZsaWN0IHZzIGEgY291bnRyeSB0aGF0IHJlYWN0cyB0byBhZ2dyZXNzaW9uIGlzIHZlcnkgZGlmZmVyZW50LiBHZXJtYW55IGlzIGEgZ29vZCBleGFtcGxlIGJlY2F1c2UgR2VybWFueSB3YXMgYSByZWFjdGl2ZSBwYXJ0aWNpcGFudCBpbiBXV0ksIG9ubHkgZW5nYWdpbmcgb25jZSBBdXN0cmlhLUh1bmdhcnkgZGVjbGFyZWQgd2FyIG9uIFNlcmJpYSBhbmQgYW4gaW5zdGlnYXRvciBpbiBXV0ksIHdoZW4gaXQgaW52YWRlZCBQb2xhbmQgb2ZmaWNpYWxseSBzdGFydGluZyBXV0lJLgoKV2UgZm91bmQgdGhhdCBmb3IgYSByZWFjdGl2ZSBwYXJ0aWNpcGFudCwgdGhlIG1pbGl0YXJ5IGV4cGVuZGl0dXJlcyByYXRpbyBhbmQgbWlsaXRhcnkgcGVyc29ubmVsIHJhdGlvcyBpbmNyZWFzZSBkdXJpbmcgdGhlIHdhciwgbm90IGJlZm9yZS4gVGhlIHBhcnQgb2YgdGhlIGdyYXBoIGhpZ2hsaWdodGVkIGluIGdyZWVuIHNob3dzIEdlcm1hbnkgaW5jcmVhc2UgaXRzIG1pbGl0YXJ5IGludmVzdG1lbnQgZHVyaW5nIFdXSS4gVGhlcmUgd2FzIG5vdCBtdWNoIGluZGljYXRpb24gb2YgYW4gaW5jcmVhc2UgaW4gaW52ZXN0bWVudCBiZWZvcmUgdGhlIHdhciBzdGFydGVkLiBPbiB0aGUgb3RoZXIgaGFuZCwgdGhlIGFyZWEgaGlnaGxpZ2h0ZWQgaW4gcmVkIGJlZm9yZSBXV0lJLCBzaG93cyBHZXJtYW55IHByb2FjdGl2ZWx5IGluY3JlYXNpbmcgbWlsaXRhcnkgaW52ZXN0bWVudC4gVGhlcmUgaXMgc2hhcnAgaW5jcmVhc2UgaW4gbWlsaXRhcnkgZXhwZW5kaXR1cmVzIGluIHRoZSAxMCB5ZWFycyBiZWZvcmUgV1dJSSBhbmQgYW4gZXZlbiBzaGFycGVyIGluY3JlYXNlIGluIG1pbGl0YXJ5IHBlcnNvbm5lbCBpbiB0aGUgMS0yIHllYXJzIGJlZm9yZSBXV0lJLiBXZSBmb3VuZCB0aGlzIHBhdHRlcm4gd2l0aCBzZXZlcmFsIGNvdW50cmllcyB0aGF0IGluc3RpZ2F0ZWQgd2Fycy4gQWx0aG91Z2ggdGhlcmUgYXJlIG1hbnkgZmFjdG9ycyB0aGF0IGRldGVybWluZSBpZiBhIGNvdW50cnkgd2lsbCBpbnN0aWdhdGUgYSB3YXIsIG1vbml0b3JpbmcgdGhlIG1pbGl0YXJ5IGludmVzdG1lbnQgY2FuIGFzc2lzdCBpbiBkZXRlcm1pbmluZyB0aGUgYWN0aW9ucyBvZiBhIGNvdW50cnkgaW4gdGhlIG5lYXIgZnV0dXJlLiAgCiAKCioqQWxsaWFuY2VzKioKCkFsbGlhbmNlcyBiZXR3ZWVuIG5hdGlvbnMgYXJlIHZlcnkgaW1wb3J0YW50IGluIGRldGVybWluaW5nIHRoZSBjb3Vyc2Ugb2YgZXZlbnRzLiBXb3JsZCBXYXIgSSBjYW4gYmUgYXR0cmlidXRlZCB0byB0aGUgdmFyaW91cyBhbGxpYW5jZXMgaW4gcGxhY2UgdGhhdCBjcmVhdGVkIGEgZGlwbG9tYXRpYyBjaGFpbiBvZiBldmVudHMgdG8gaW52b2x2ZSBhbGwgdGhlIHdvcmxkIHBvd2VycyBhdCB0aGF0IHRpbWUuIEJlbG93IGlzIGEgc2VyaWVzIG9mIGJveHBsb3RzIHRvIHNob3cgdGhlIG51bWJlciBvZiBhbGxpYW5jZXMgaW4gZWZmZWN0IHBlciB5ZWFyIHNpbmNlIDE5MDBzOyB0aGUgY29sb3JlZCBib3ggcGxvdHMgc2hvdyB0aGUgZGlmZmVyZW50IGV2ZW50cyBsaXN0ZWQgYWJvdmUuIFdlIHNlZSB0aGF0IHRoZSBtZWRpYW4gbnVtYmVyIG9mIGFsbGlhbmNlcyBwZXIgY291bnRyeSBpbmNyZWFzZSB0b3dhcmRzIHRoZSBlbmQgb2YgZWFjaCB3YXIsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiB0aGUgQWZnaGFuaXN0YW4gV2FyLiAgV2UgaGF2ZSBmb3VuZCB0aGF0IGFsbGlhbmNlcyBhcmUgYSByZWFjdGl2ZSB0byB3YXJzLiBGb3IgZXhhbXBsZSwgdGhlIE5vcnRoIEF0bGFudGljIFRyZWF0eSBPcmdhbml6YXRpb24oTkFUTykgYW5kIHRoZSBXYXJzYXcgUGFjdCB3ZXJlIHRyZWF0aWVzIGNyZWF0ZWQgdG93YXJkcyB0aGUgZW5kIG9mIFdXSUkuIEJvdGggYWxsaWFuY2VzIGludm9sdmVkIG51bWVyb3VzIGNvdW50cmllcyBhbmQgYWNjb3VudCBmb3IgdGhlIGluY3JlYXNlIHRoZSBudW1iZXIgb2YgYWxsaWFuY2VzIHRvd2FyZHMgdGhlIGVuZCBvZiBXV0lJIGFuZCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBDb2xkIFdhci4gV2UgYWxzbyBmb3VuZCB0aGF0IG9uY2UgYSBtaWxpdGFyeSBhbGxpYW5jZSBpcyB0ZXJtaW5hdGVkIG9yIGRpc3NvbHZlZCwgY291bnRyaWVzIHRyeSB0byBqb2luIGFub3RoZXIgdHJlYXR5IGFzIHF1aWNrbHkgYXMgcG9zc2libGUuIFRvd2FyZHMgdGhlIGVuZCBvZiB0aGUgQ29sZCBXYXIsIHRoZSBTb3ZpZXQgVW5pb24gZGlzc29sdmVkIGFuZCB3aXRoIGl0IHRoZSBXYXJzYXcgUGFjdC4gT25jZSB0aGF0IGVuZGVkLCBtYW55IGNvdW50cmllcyBqb2luZWQgTkFUTyB3aGljaCBhY2NvdW50cyBmb3IgdGhlIGluY3JlYXNlIGluIHRoZSBhbGxpYW5jZXMgdG93YXJkcyB0aGUgZW5kIG9mIHRoZSBDb2xkIFdhci4gT3ZlcmFsbCwgbG9va2luZyBhdCBhbGxpYW5jZXMgaXMgbm90IGEgZ29vZCBwcmVkaWN0b3Igb2YgZXZlbnRzIHRvIGNvbWUgYmVjYXVzZSB0aGVyZSBhcmUgYSBsb3Qgb2YgZGlwbG9tYXRpYyBldmVudHMgZ29pbmcgb24gaW4gdGhlIGJhY2tncm91bmQgdGhhdCBpcyBub3QgY2FwdHVyZWQgaW4gdGhlIGRhdGEuIEFkZGl0aW9uYWxseSwgdG9kYXkgdGhlIFVuaXRlZCBOYXRpb25zIGhhcyBhIGxvdCBvZiBjb250cm9sIGFuZCByZWd1bGF0aW9uIG92ZXIgd2FycyB0aGF0IGhhcHBlbiB0b2RheSwgc28gbG9va2luZyBhdCBhbGxpYW5jZXMgd2lsbCBub3QgYmUgYSBzdWZmaWNpZW50IHRvIGRldGVybWluZSBmdXR1cmUgZXZlbnRzLiAKCiAgCmBgYHtyLCBlY2hvID0gRkFMU0V9CgpkYXlkX2FsX3llYXIgPC0gZmlsdGVyKGR5YWRfYWxfeWVhciwgZHlhZF9hbF95ZWFyJHllYXIgJWluJSBjKDE5MDA6MjAxMikpCmR5YWRfYWxfeWVhciRsZW5ndGggPSBkeWFkX2FsX3llYXIkZHlhZF9lbmRfeWVhciAtIGR5YWRfYWxfeWVhciRkeWFkX3N0X3llYXIKCmRheWRfYWxfeWVhciRjb25mbGljdCA8LSAiMCIKZHlhZF9hbF95ZWFyJGNvdW50IDwtIDEgCgpkaXJfYWxsaWFuY2VzIDwtIGdhdGhlcihkaXJfYWxfeWVhciwgdHJlYXR5X3R5cGUsIGlkaWNhdG9yLCBkZWZlbnNlOmVudGVudGUpCmRpcl9hbGxpYW5jZXMgPC0gZGlyX2FsbGlhbmNlc1shZGlyX2FsbGlhbmNlcyRpZGljYXRvciAlaW4lICAwLF0KZGlyX2FsbGlhbmNlcyRkeWFkX2VuZF95ZWFyW2Rpcl9hbGxpYW5jZXMkZHlhZF9lbmRfeWVhciAlaW4lIE5BXSA9IDIwMTYKZGlyX2FsbGlhbmNlcyA8LSBkaXJfYWxsaWFuY2VzW2Rpcl9hbGxpYW5jZXMkeWVhcj4xOTAwLF0KYWxsaWFuY2VfY291bnQgPC0gZGlyX2FsbGlhbmNlc1ssIGMoMiwzLDE0LDE2KV0KYWxsaWFuY2VfY291bnQkY291bnQgPC0gMSAKCmdwX2N0IDwtIGFnZ3JlZ2F0ZShjYmluZChjb3VudCkgfiBjY29kZTErc3RhdGVfbmFtZTEreWVhcit0cmVhdHlfdHlwZSwgZGF0YSA9YWxsaWFuY2VfY291bnQsIEZVTiA9IHN1bSApCmdwX2N0JENvbmZsaWN0IDwtICIwIgoKZm9yKGkgaW4gYygxOmxlbmd0aChkJHgxKSkpewogIGdwX2N0W2dwX2N0JHllYXIgPj0gZCR4MVtpXSAmIGdwX2N0JHllYXIgPD0gZCR4MltpXSwgbGVuZ3RoKGdwX2N0KV0gPC0gYXMuY2hhcmFjdGVyKGkpCn0KCmBgYAogIApgYGB7ciBmaWcud2lkdGg9MjAsIGZpZy5oZWlnaHQ9OCwgZWNobyA9IEZBTFNFfQpnZ3Bsb3QoKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJDb3VudCIpKwogIGdlb21fYm94cGxvdChkYXRhID0gZ3BfY3QsIGFlcyh4ID0gYXMuZmFjdG9yKHllYXIpLCB5ID0gY291bnQsIGZpbGwgPSBDb25mbGljdCkpICsKICBnZ3RpdGxlKCJUb3RhbCBBbGxpYW5jZXMgYnkgWWVhciIpICsgCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSwgc2l6ZSA9IDIwKSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgc2l6ZSA9IDEwKSwgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9MTUpLCAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTUpKSsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Yygid2hpdGUiLCAibGlnaHRzdGVlbGJsdWUzIiwgInBpbmszIiwgInBhbGV0dXJxdW9pc2UzIiwgImxpZ2h0c3RlZWxibHVlMiIsICJsaWdodHN0ZWVsYmx1ZTQiLCJzYWxtb24iICksIGxhYmVscyA9IG15bGFibGVzKQoKYGBgCgoKCioqTWlsaXRhcml6ZWQgSW50ZXJzdGF0ZSBEaXNwdXRlcyoqICAKSW4gdGhlIHllYXJzIGxlYWRpbmcgdG8gYSB3YXIsIGNlcnRhaW4gY291bnRyaWVzIGluY3JlYXNlZCB0aGVpciBtaWxpdGFyeSBhcnNlbmFsLCByZWNydWl0ZWQgbW9yZSBwZXJzb25uZWwgYW5kIHRlc3RlZCBvdXQgdGhlaXIgd2VhcG9ucyBhbmQgd2FyZmFyZSBzdHJhdGVnaWVzIG9uIGEgc21hbGxlciBzY2FsZSB3aXRoIGEgZmVlYmxlIG9wcG9uZW50LiBUaG91Z2ggb3VyIGV4cGxvcmF0aW9uIG9mIE1pbGl0YXJpemVkIEludGVyc3RhdGUgRGlzcHV0ZXMsIHdlIHNlZSBleGFjdGx5IHRoYXQuIEZvciBpbnN0YW5jZSwgaW4gdGhlIHllYXJzIGxlYWRpbmcgdG8gV1dJSSwgSXRhbHkgYW5kIEdlcm1hbnkgaGFkIGluaXRpYXRlZCB0aGUgbW9zdCBudW1iZXIgb2YgZGlzcHV0ZXMuIENsZWFybHkgYWxsIHRoZSBwcmVwYXJhdGlvbiBhbmQgd2FyLXJlYWRpbmVzcyBwcmVwYXJlZCB0aGVtIGZvciBsYXJnZXIgc2NhbGUgZW5jb3VudGVycyBhbmQgYWdhaW5zdCBtb3JlIGZvcm1pZGFibGUgZm9lcy4gVGhpcyBncmFwaCBiZWxvdyBwbG90cyB0aGUgbW9zdCBiZWxsaWdlcmVudCBjb3VudHJpZXMgZWFjaCB5ZWFyIGFnYWluc3QgdGhlIG51bWJlciBvZiBjb25mbGljdHMgdGhhdCBpdCBoYWQgaW5pdGlhdGVkLiBUaGUgaW5mb3JtYXRpb24gaXMgc3VwZXJpbXBvc2VkIHdpdGggZGlmZmVyZW50IHdhciBwZXJpb2RzLiBUbyByZWR1Y2UgY2x1dHRlciwgd2XigJl2ZSBvbWl0dGVkIG9ic2VydmF0aW9ucyBiZWxvdyBzaXggY29uZmxpY3RzIGVhY2ggeWVhci4gQXMgc2VlbiBhYm92ZSwgdGhlIHRvcCBpbml0aWF0b3JzIG9mIGNvbmZsaWN0cyBoYWQgYSByZWFkeSBwcmVkaXNwb3NpdGlvbiB0b3dhcmRzIGFuIGVzY2FsYXRpb24gb3IgaW1wZW5kaW5nIHdhci4gT25jZSB3ZSBkZWx2ZWQgaW50byB0aGUgZGlmZmVyZW50IGRpbWVuc2lvbnMgb2YgdGhlIGRhdGEsIHdlIHBhaWQgc3BlY2lhbCBhdHRlbnRpb24gdG8gdGhlIGJvdW5kYXJ5IHllYXJzIHN1cnJvdW5kaW5nIGEgd2FyLiBCYXNlZCBvbiBvdXIgb2JzZXJ2YXRpb25zLCB3ZSBjb3VsZCB0ZWxsIHRoYXQgdGhlIG51bWJlciBvZiBmYXRhbGl0aWVzIGluIGNvbmZsaWN0cyBkdXJpbmcgdGhlIHllYXJzIGJlZm9yZSBhIHdhciB3YXMgaW5kaWNhdGl2ZSBvZiB0aGUgZmFjdCB0aGF0IGEgaW50ZXJuYXRpb25hbCBpbnZvbHZlbWVudCBpbiBhIHdhciBzZWVtZWQgaW1taW5lbnQuCgpgYGB7ciBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9NywgZWNobz1GQUxTRX0KbGlicmFyeShnZ3JlcGVsKQoKTUlEQiA9IHJlYWQuY3N2KGZpbGU9Ii4vZGF0YS9NSUQvTUlEQl80LjAxLmNzdiIsIHNlcD0gIiwiKQoKI0ZpbHRlciBieSBjb3VudHJpZXMgdGhhdCBvcmlnaW5hdGVkIGRpc3B1dGVzLgpNSURCX08gPC0gZmlsdGVyKE1JREIsIE9yaWc9PTEpCgojQ291bnQgdGhlIGNvbmZsaWN0cyBvcmlnaW5hdGVkIGJ5IGNvdW50cmllcyBlYWNoIHllYXIKV2FyT3JpZyA8LSBNSURCX08gJT4lIGNvdW50KFN0QWJiLCBzb3J0PVRSVUUsIHZhcnM9U3RZZWFyKQoKI1RvcCBDb25mbGljdHMgc3RhcmVkICBDb3VudHJpZXMgYnkgWWVhcgpzdGFydF95ciA8LSAxOTAxCmVuZF95ciA8LSAyMDEwCgojc3RhcnRfeXIgPC0gMTkzOAojZW5kX3lyIDwtIDE5NDIKZm9yKHlyIGluIHN0YXJ0X3lyOmVuZF95cikgIAp7CiAgI0NvdW50IG9mIGxhcmdlc3QgbnVtYmVyIG9mIGNvbmZsaWN0cyB0aGF0IHllYXIuCiAgdG9wX28gPC0gaGVhZChhcnJhbmdlKGZpbHRlcihXYXJPcmlnLCB2YXJzPT15ciksIGRlc2MobikpLCAxKVsxLCAzXQoKICAjU2VsZWN0IHJvd3Mgb2YgYWxsIGNvdW50cmllcyB3aXRoIHRoZSB0b3AgY291bnQgb2YgY29uZmxpY3RzLgogIFdhck9yaWdfeXIgPC0gZmlsdGVyKFdhck9yaWcsIHZhcnM9PXlyICYgbj09dG9wX28kbltbMV1dKQogICAgCiAgaWYoeXIgPT0gc3RhcnRfeXIpCiAgICBXYXJUb3BPcmlnIDwtIFdhck9yaWdfeXIKICBlbHNlCiAgICBXYXJUb3BPcmlnIDwtIHJiaW5kKFdhclRvcE9yaWcsIFdhck9yaWdfeXIpCn0KCldhclRvcE9yaWcgPC0gYXJyYW5nZShXYXJUb3BPcmlnLCBkZXNjKHZhcnMpKQojcHJpbnQoV2FyVG9wT3JpZykKCiMgT3ZlcmxheSB3LyByZWN0YW5nbGUgdGhlbWUKeTJfaGlnaCA9MzAKZCA9IGRhdGEuZnJhbWUoeDE9YygxOTE0LDE5MzksIDE5NDcsIDE5NTAsIDE5NTUsIDIwMDEpLCB4Mj1jKDE5MTgsIDE5NDUsIDE5OTEsIDE5NTMsIDE5NzUsIDIwMTApLCB5MT1jKDAsMCwwLDAsMCwwKSwgeTI9Yyh5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCx5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCksIENvbmZsaWN0PWMoIldXSSIsICJXV0lJIiwgIkNvbGQgV2FyIiwgIktvcmVhbiBXYXIiLCAiVmlldG5hbSBXYXIiLCAiQWZnaGFuaXN0YW4gV2FyIiksIHI9YygxLDIsMyw0LDUsNikpCgoKI1VzaW5nIGRpc3RpbmN0IGNvbG9yIHBhbGV0dGUKY29scyA8LSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoMTIsICJQYWlyZWQiKSkKbXlQYWwgPC0gY29scyhsZW5ndGgodW5pcXVlKFdhclRvcE9yaWckU3RBYmIpKSkKCmNvbmZpY3RzSW5pdGlhdGVkID0gNQpnZ3Bsb3QoKSArIAogIGdlb21fcG9pbnQoZGF0YT1XYXJUb3BPcmlnLCBhZXMoeCA9IHZhcnMsIHkgPSBuKSwgc2l6ZSA9IDEsIGNvbG9yID0gJ3JlZCcpICsKICBnZW9tX2xhYmVsX3JlcGVsKGRhdGE9V2FyVG9wT3JpZywKICAgIGFlcyh4ID0gdmFycywgeSA9IG4sIAogICAgICAgIGxhYmVsPSBpZmVsc2Uobj49Y29uZmljdHNJbml0aWF0ZWQsIGFzLmNoYXJhY3RlcihTdEFiYiksICcnKSwKICAgICAgICBmaWxsID0gaWZlbHNlKG4+PWNvbmZpY3RzSW5pdGlhdGVkLCBhcy5jaGFyYWN0ZXIoU3RBYmIpLCAnV1dJJykpLAogICAgICAgICNmaWxsID0gZmFjdG9yKFN0QWJiKSksCiAgICAgIGZvbnRmYWNlID0gJ2JvbGQnLCBjb2xvciA9ICd3aGl0ZScsCiAgICAgIGJveC5wYWRkaW5nID0gdW5pdCgwLjM1LCAibGluZXMiKSwKICAgICAgcG9pbnQucGFkZGluZyA9IHVuaXQoMC41LCAibGluZXMiKSwKICAgICAgc2VnbWVudC5jb2xvciA9ICdncmV5NTAnKSArCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj14MSwgeG1heD14MiwgeW1pbj15MSwgeW1heD15MiwgZmlsbD1Db25mbGljdCksIGFscGhhPTAuMTUsIHNob3cubGVnZW5kID0gVFJVRSkgKwogIHRoZW1lX2NsYXNzaWMoYmFzZV9zaXplID0gMTYpICsKICBnZ3RpdGxlKCJDb3VudHJpZXMgSW5pdGlhdGluZyBNb3N0IE51bWJlciBPZiBDb25mbGljdHMgRWFjaCBZZWFyIikgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiQ291bnQiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpICsKICBndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IldhciBQZXJpb2QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUucG9zaXRpb24gPSAibGVmdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5yb3c9MSkpICsKICBzY2FsZV9maWxsX21hbnVhbCggCiAgICBicmVha3M9IGMoIldXSSIsICJXV0lJIiwgIkNvbGQgV2FyIiwgIktvcmVhbiBXYXIiLCAiVmlldG5hbSBXYXIiLCAiQWZnaGFuaXN0YW4gV2FyIiksIHZhbHVlcz0gbXlQYWwpCiAgCmBgYAoKICAKIyMgTWFpbiBBbmFseXNpcyAKCiMjIyNOYXRpb25hbCBNYXRlcmlhbHMgQ2FwYWJpbGl0aWVzCgpgYGB7cn0KTk1DIDwtIE5NQ19vcmlnIApOTUMkY2luY1tOTUMkY2luYyA9PSAtOXwgaXMubmEoTk1DJGNpbmMpXSA8LSAwCk5NQyRpcnN0W05NQyRpcnN0ID09IC05fCBpcy5uYShOTUMkaXJzdCldIDwtIDAKTk1DJG1pbGV4W05NQyRtaWxleCA9PSAtOXwgaXMubmEoTk1DJG1pbGV4KV0gPC0gMApOTUMkbWlscGVyW05NQyRtaWxwZXI9PSAtOXwgaXMubmEoTk1DJG1pbHBlcildIDwtIDAKTk1DJHBlY1tOTUMkcGVjID09IC05fCBpcy5uYShOTUMkcGVjKV0gPC0gMApOTUMkdHBvcFtOTUMkdHBvcCA9PSAtOXwgaXMubmEoTk1DJHRwb3ApXSA8LSAwCk5NQyR1cG9wW05NQyR1cG9wID09IC05fCBpcy5uYShOTUMkdXBvcCldIDwtIDAKCmFsbF95ZWFyIDwtIGMoMTkwMDoyMDA3KQoKTk1DX3JhdGlvcyA8LSBjKCIiKQpmb3IgKHllYXJfdCBpbiBhbGxfeWVhcil7CiAgeXIgPC0gZmlsdGVyKE5NQywgTk1DJHllYXIgJWluJSB5ZWFyX3QpIAogIG1heCA8LSBhcHBseSh5clssIGMoNDo5KV0sIDIsIHN1bSkKICAjbWF4IDwtIGFzLm51bWVyaWMobWF4WzQ6OV0pCiAgZm9yIChpIGluIDQ6OSl7CiAgICB5clssaV0gPSBhcy5udW1lcmljKHlyWyxpXS9tYXhbaS0zXSkKICB9CiAgTk1DX3JhdGlvcyA8LSBzbWFydGJpbmQoTk1DX3JhdGlvcyAsIHlyKQp9CgpOTUNfcmF0aW9zICA8LSBOTUNfcmF0aW9zIFtjKDI6bnJvdyhOTUNfcmF0aW9zICkpLCBjKDI6bGVuZ3RoKE5NQ19yYXRpb3MpKV0KCgpjYmJQYWxldHRlIDwtIGMoIiMwMDAwMDAiLCAiI0U2OUYwMCIsICIjNTZCNEU5IiwgIiMwMDlFNzMiLCAiI0YwRTQ0MiIsICIjMDA3MkIyIiwgIiNENTVFMDAiLCAiI0NDNzlBNyIpCgpgYGAKCgpOYXRpb25hbCBNYXRlcmlhbHMgQ2FwYWJpbGl0eSBtZWFzdXJlcyB0aGUgcG93ZXIgb2YgYSBjb3VudHJ5IGJhc2VkIG9uIDYgdmFsdWVzOiB0b3RhbCBwb3B1bGF0aW9uLCB1cmJhbiBwb3B1bGF0aW9uLCBtaWxpdGFyeSBwZXJzb25uZWwsIG1pbGl0YXJ5IGV4cGVuZGl0dXJlcywgaXJvbiBhbmQgc3RlZWwgcHJvZHVjdGlvbiBhbmQgZW5lcmd5IGNvbnN1bXB0aW9uLiBOTUMgaXMgcHVyZWx5IGEgbWVhc3VyZSBvZiBtaWxpdGFyeSBhbmQgZWNvbm9taWMgbWVhbnMgb2YgaW5mbHVlbmNlIHJhdGhlciB0aGFuIGRpcGxvbWFjeSBvciBvdGhlciBmb3JtcyBvZiBpbmZsdWVuY2UuIAoKQ0lOQyBpcyB0aGUgY29tcG9zaXRlIHNjb3JlIHRvIG1lYXN1cmUgdGhlIHBvd2VyIG9mIGEgY291bnRyeSB1c2luZyB0aGUgYXZlcmFnZSBvZiB0aGUgcmF0aW9zIG9mIGVhY2ggY291bnRyeSB2YWx1ZSB0byB0aGUgdG90YWwgdmFsdWUgb2YgYWxsIGNvdW50cmllcyBmb3IgZWFjaCBvZiB0aGUgNiBmYWN0b3JzLiAgIEJlbG93IGlzIHRoZSBDTklDIHNjb3JlIGZvciBtYWpvciBwb3dlcnMgdG9kYXkgd2hvIGFsc28gcGFydGljaXBhdGVkIHRoZSBtYWpvciB3YXJzIGluIHRoZSBwYXN0LiBBbHNvIGhpZ2hsaWdodGVkIGFyZSB0aGUgcGVyaW9kIHdhcnMgbWVudGlvbmVkIGFib3ZlLgoKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD01fQpjb3VudHJpZXMgPC0gYygiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIiwgIlVuaXRlZCBLaW5nZG9tIiwgIkZyYW5jZSIsICJSdXNzaWEiLCJHZXJtYW55IiwgIkphcGFuIiwgIkNoaW5hIikKY291bnRyeV9jb2RlIDwtIG1lbWJlcl9hbGxpYW5jZXMkY2NvZGVbbWF0Y2goY291bnRyaWVzLCBtZW1iZXJfYWxsaWFuY2VzJHN0YXRlX25hbWUpXQoKTk1DX21wIDwtIGZpbHRlcihOTUMsIE5NQyR5ZWFyICVpbiUgYWxsX3llYXIpCk5NQ19tcCA8LSBmaWx0ZXIoTk1DX21wLCBOTUNfbXAkY2NvZGUgJWluJSBjb3VudHJ5X2NvZGUpCk5NQ19tcCRjb3VudHJ5ID0gIiIKZm9yKCBpIGluIGMoMTpsZW5ndGgoY291bnRyeV9jb2RlKSkpewogIE5NQ19tcCRjb3VudHJ5W05NQ19tcCRjY29kZSA9PSBjb3VudHJ5X2NvZGVbaV1dIDwtIGNvdW50cmllc1tpXQp9CgpnZ3Bsb3QoKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJZZWFyIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZT0iQ0lOQyIpICsKICBsYWJzKGNvbG9yID0nQ291bnRyeScpKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD1tYXgoTk1DX21wJGNpbmMpLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjE1KSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfbXAsIGFlcyh4ID0geWVhciwgeSA9IGNpbmMsIGNvbG9yID0gY291bnRyeSwgZ3JvdXAgPSBzdGF0ZWFiYikpICsKICBnZ3RpdGxlKCJDTklDIGJ5IFllYXIgZm9yIE1ham9yIFBvd2VycyBUb2RheSIpICsgCiAgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksIGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSAKICAKCgoKYGBgCgoKQXMgeW91IGNhbiBzZWUgQ05JQyBpcyBjb25zdGFudGx5IGNoYW5naW5nLiBJbnRlcmVzdGluZ2x5LCB0aGUgQ05JQyBzcGlrZXMgZm9yIHRoZSBVUyByaWdodCBhZnRlciBXV0kgYW5kIFdXSUkgd2hlcmUgdGhlIFVTIGhhZCBhIG1ham9yIHJvbGUgaW4gdGhlIG91dGNvbWUgb2YgdGhlIHdhcnMuIFRoZXJlIGlzIGFsc28gYW4gaW5jcmVhc2UgaW4gdGhlIFVT4oCZcyBDSU5DIHNjb3JlIGR1cmluZyB0aGUgS29yZWFuIFdhci4gRm9sbG93aW5nIHRoZSBLb3JlYW4gV2FyLCB0aGUgVVPigJlzIENJTkMgc2NvcmUgc2hvd3MgYSBjb250aW51b3VzIGRlY3JlYXNlIGR1cmluZyB0aGUgVmlldG5hbSB3aGVyZSB0aGUgVVMgbG9zdCB0aGUgd2FyLiAgQXQgdGhlIGVuZCBvZiBXV0ksIHlvdSBzZWUgUnVzc2lh4oCZcyBDTklDIGRpcCBsb3cgYnV0IGl0IGJvdW5jZWQgYmFjayB0byBpdHMgQ05JQyBiZWZvcmUgV1dJIHF1aWNrbHkuIER1cmluZyB0aGUgVmlldG5hbSBXYXIsIFJ1c3NpYSBzdXBwb3J0ZWQgdGhlIFZpZXRuYW1lc2UgcGVvcGxlIGFuZCB5b3Ugc2VlIHRoZSBpdHMgQ0lOQyBzY29yZSBpbmNyZWFzZSBhYm92ZSB0aGF0IG9mIHRoZSBVUyBhcyB0aGV5IHN0YXJ0IHRvIGdhaW4gZ3JvdW5kIGluIHRoZSB3YXIuIEFsc28sIFJ1c3NpYeKAmXMgQ0lOQyBzY29yZSBkcm9wcyBsb3cgdG93YXJkcyB0aGUgZW5kIG9mIHRoZSBDb2xkIFdhciBhcyB0aGUgc2F0ZWxsaXRlIHN0YXRlcyBzdGFydCBnYWluaW5nIHRoZWlyIGluZGVwZW5kZW5jZSBhbmQgdGhlIFVTU1Igd2FzIGRpc3NvbHZlZCAoQmF0dGxlZmllbGQ6IFZpZXRuYW0pLgoKVG8gZXhwbG9yZSB0aGUgdHJlbmRzIG1vcmUsIHRoZSBkYXRhIHdhcyByZWZpbmVkIHRvIG9ubHkgbG9vayBhdCB0aGUgbWFqb3IgcGFydGljaXBhbnRzIG9mIGVhY2ggd2FyLiBGb3IgZXhhbXBsZSwgd2l0aCBXV0kgd2UgbG9va2VkIGF0IHRoZSBDSU5DIHZhbHVlcyBmb3IgbWFqb3IgcGxheWVycyBpbiB0aGUgQWxsaWVkIFBvd2VycyBhbmQgQ2VudHJhbCBQb3dlcnMgYSBmZXcgeWVhcnMgYmVmb3JlIGFuZCBhZnRlciB0aGUgd2FyLiBXZSByZXBsaWNhdGVkIHRoaXMgcHJvY2VzcyBmb3IgYWxsIHRoZSBldmVudHMgbGlzdGVkIGFib3ZlLiBCZWxvdyBhcmUgQ0lOQyBncmFwaHMgdXNpbmcgdGhpcyBhcHByb2FjaCBmb3IgV1dJIGFuZCBXV0lJLgoKCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NSwgRWNobyA9IFRSVUV9CmFsbGllZCA8LSBjKCJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCAiVW5pdGVkIEtpbmdkb20iLCAiUnVzc2lhIiwgIkphcGFuIiwgIkl0YWx5IikKYWxsaWVkX2Njb2RlIDwtIG1lbWJlcl9hbGxpYW5jZXMkY2NvZGVbbWF0Y2goYWxsaWVkLCBtZW1iZXJfYWxsaWFuY2VzJHN0YXRlX25hbWUpXQoKY2VudHJhbCA8LSBjKCJHZXJtYW55IiwgIlR1cmtleSIsICJBdXN0cmlhLUh1bmdhcnkiLCAiUm9tYW5pYSIsICJCdWxnYXJpYSIpCmNlbnRyYWxfY2NvZGUgPC0gbWVtYmVyX2FsbGlhbmNlcyRjY29kZVttYXRjaChjZW50cmFsLCBtZW1iZXJfYWxsaWFuY2VzJHN0YXRlX25hbWUpXQoKV1dJX3JhbmdlID0gYygxOTA0OjE5MzApCgpXV0k8LSBmaWx0ZXIoTk1DLCBOTUMkeWVhciAlaW4lIFdXSV9yYW5nZSkKYWxsaWVkUDwtIGZpbHRlcihXV0ksIFdXSSRjY29kZSAlaW4lIGFsbGllZF9jY29kZSkKYWxsaWVkUCRzaWRlID0gIkFsbGllZCBQb3dlcnMiCmZvciggaSBpbiBjKDE6bGVuZ3RoKGFsbGllZF9jY29kZSkpKXsKICBhbGxpZWRQJGNvdW50cnlbYWxsaWVkUCRjY29kZSA9PSBhbGxpZWRfY2NvZGVbaV1dIDwtIHBhc3RlKGFsbGllZFtpXSwiKEFsbGllZCkiLCBzZXAgPSAiICIpCn0KCmNlbnRyYWxQPC0gZmlsdGVyKFdXSSwgV1dJJGNjb2RlICVpbiUgY2VudHJhbF9jY29kZSkKY2VudHJhbFAkc2lkZSA9ICJDZW50cmFsIFBvd2VycyAiCmZvciggaSBpbiBjKDE6bGVuZ3RoKGNlbnRyYWxfY2NvZGUpKSl7CiAgY2VudHJhbFAkY291bnRyeVtjZW50cmFsUCRjY29kZSA9PSBjZW50cmFsX2Njb2RlW2ldXSA8LSBwYXN0ZShjZW50cmFsW2ldLCAiKENlbnRyYWwpIiwgc2VwID0gIiAiKQp9CldXSSA8LXJiaW5kKGFsbGllZFAsIGNlbnRyYWxQKQoKd3cxIDwtIGdncGxvdCgpICsgCiAgbGFicyhjb2xvciA9J0NvdW50cnknKSsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkNOSUMiKSsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPTE5MTQsIHhtYXg9MTkxOCwgeW1pbj0wLCB5bWF4PS40KSxhbHBoYT0wLjA1LCBmaWxsID0ic2FsbW9uIikgKwogIGdlb21fbGluZShkYXRhID0gV1dJLCBhZXMoeCA9IHllYXIsIHkgPSBjaW5jLCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsgCiAgZmFjZXRfd3JhcCh+c2lkZSkgKyAKICB0aGVtZV9jbGFzc2ljKCkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIGdndGl0bGUoIkNOSUMgU2NvcmU6IFdXSSBNYWpvciBQbGF5ZXJzICIpKwogICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGxlZ2VuZC5wb3NpdGlvbj0icmlnaHQiKQoKCmFsbGllcyA8LSBjKCJVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EiLCAiVW5pdGVkIEtpbmdkb20iLCAiRnJhbmNlIiwgIlJ1c3NpYSIsICJBdXN0cmFsaWEiLCJDaGluYSIpCmFsbGllc19jY29kZSA8LSBtZW1iZXJfYWxsaWFuY2VzJGNjb2RlW21hdGNoKGFsbGllcywgbWVtYmVyX2FsbGlhbmNlcyRzdGF0ZV9uYW1lKV0KCmF4aXMgPC0gYygiR2VybWFueSIsICJJdGFseSIsICJKYXBhbiIsICJIdW5nYXJ5IiwgIlJvbWFuaWEiLCAiQnVsZ2FyaWEiKQpheGlzX2Njb2RlIDwtIG1lbWJlcl9hbGxpYW5jZXMkY2NvZGVbbWF0Y2goYXhpcywgbWVtYmVyX2FsbGlhbmNlcyRzdGF0ZV9uYW1lKV0KCldXSUlfcmFuZ2UgPSBjKDE5MzQ6MTk1MCkKCldXSUk8LSBmaWx0ZXIoTk1DLCBOTUMkeWVhciAlaW4lIFdXSUlfcmFuZ2UpCmFsbGllZFAyPC0gZmlsdGVyKFdXSUksIFdXSUkkY2NvZGUgJWluJSBhbGxpZXNfY2NvZGUpCmFsbGllZFAyJHNpZGUgPSAiQWxsaWVzIgpmb3IoIGkgaW4gYygxOmxlbmd0aChhbGxpZXNfY2NvZGUpKSl7CiAgYWxsaWVkUDIkY291bnRyeVthbGxpZWRQMiRjY29kZSA9PSBhbGxpZXNfY2NvZGVbaV1dIDwtIHBhc3RlKGFsbGllc1tpXSwgIihBbGxpZXMpIiwgc2VwID0gIiAiKQp9CgpheGlzUDwtIGZpbHRlcihXV0lJLCBXV0lJJGNjb2RlICVpbiUgYXhpc19jY29kZSkKYXhpc1Akc2lkZSA9ICJBeGlzIgpmb3IoIGkgaW4gYygxOmxlbmd0aChheGlzX2Njb2RlKSkpewogIGF4aXNQJGNvdW50cnlbYXhpc1AkY2NvZGUgPT0gYXhpc19jY29kZVtpXV0gPC0gcGFzdGUoYXhpc1tpXSwgIihBeGlzKSIsIHNlcCA9ICIgIikKfQoKV1dJSSA8LXJiaW5kKGFsbGllZFAyLCBheGlzUCkKCnd3MiA8LSBnZ3Bsb3QoKSArIAogIGxhYnMoY29sb3IgPSdDb3VudHJ5JykrCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJDTklDIikrCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj0xOTM5LCB4bWF4PTE5NDUsIHltaW49MCwgeW1heD0uNCksYWxwaGE9MC4wNSwgZmlsbCA9InBhbGV0dXJxdW9pc2UzIikgKwogIGdlb21fbGluZShkYXRhID0gV1dJSSwgYWVzKHggPSB5ZWFyLCB5ID0gY2luYywgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IHN0YXRlYWJiKSkgKyAKICBmYWNldF93cmFwKH5zaWRlKSArIAogIHRoZW1lX2NsYXNzaWMoKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgZ2d0aXRsZSgiQ05JQyBTY29yZTogV1dJSSBNYWpvciBQbGF5ZXJzICIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJyaWdodCIpCgpgYGAKCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OH0KZ3JpZC5hcnJhbmdlKHd3MSwgd3cyLCBucm93PTIpCgpgYGAKQXMgbWVudGlvbmVkLCB3aXRoIFdXSSB0aGUgVVPigJlzIENJTkMgc3Bpa2VkIHJpZ2h0IGFmdGVyIHRoZSB3YXIgYW5kIHRoZW4gYmVnYW4gdG8gc3RlYWRpbHkgZGVjcmVhc2UgdGlsbCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBXV0lJLiBSdXNzaWHigJlzIENJTkMgZHJvcHBlZCBidXQgcm9zZSBhZ2FpbiBxdWlja2x5IGFuZCBzdGF5ZWQgb24gYSByZWxhdGl2ZWx5IHVwd2FyZCB0cmVuZCB0aWxsIFdXSUkuIFVubGlrZSB0aGUgVVMgYW5kIFJ1c3NpYSwgVW5pdGVkIEtpbmdkb23igJlzIENJTkMgd2FzIHN0ZWFkaWx5IGRlY3JlYXNpbmcgYWZ0ZXIgdGhlIHdhci4gSXRhbHkgYW5kIEphcGFu4oCZcyBDSU5DIHJlbWFpbmVkIHN0ZWFkeS4gV2l0aCB0aGUgQ2VudHJhbCBQb3dlcnMgYWZ0ZXIgV1dJLCBHZXJtYW554oCZcyBDSU5DIGRyb3BwZWQgYnV0IGl0IGRpZCBub3QgcmlzZSBhZ2Fpbi4gVHVya2V54oCZcywgUm9tYW5pYeKAmXMgYW5kIEJ1bGdhcmlh4oCZcyBDSU5DIHJlbWFpbmVkIHN0ZWFkeS4gV2Ugc2VlIHRoZSBBdXN0cmlhLUh1bmdhcmlhbiBDSU5DIGRpc2FwcGVhciBhZnRlciB0aGUgd2FyIHNpbmNlIHRoZSBBdXN0cm8tSHVuZ2FyaWFuIGVtcGlyZSB3YXMgZGlzc29sdmVkIGF0IHRoZSBlbmQgb2YgdGhlIHdhciAoUm95ZGUtU21pdGgpLgoKV2l0aCBXV0lJLCB3ZSBzZWUgYSBzaW1pbGFyIHBhdHRlcm4gZm9yIHRoZSBVUyB3aGVyZSB0aGUgQ05JQyByZWFjaGVzIGEgcGVhayBhdCB0aGUgZW5kIG9mIFdXSUkgYW5kIHN0ZWFkaWx5IGRlY3JlYXNlcyB0aWxsIHRoZSBLb3JlYW4gd2FyLiBSdXNzaWEgYWxzbyBzaG93cyBhIHNpbWlsYXIgcGF0dGVybiB0byBXV0kgd2hlcmUgaXRzIENJTkMgc2NvcmUgcmVhY2hlcyBhIGxvdyBwb2ludCB0b3dhcmRzIHRoZSBlbmQgb2YgV1dJSSBhbmQgdGhlbiBjb250aW51ZXMgdG8gc3RlYWRpbHkgaW5jcmVhc2UgdGlsbCB0aGUgS29yZWFuIHdhci4gVGhlIFVLIGFsc28gZm9sbG93cyBhIHNpbWlsYXIgcGF0dGVybiB3aGVyZSBpdCBDSU5DIHBlYWtzIHJpZ2h0IGFmdGVyIHRoZSB3YXIgYW5kIHRoZW4gc3RlYWRpbHkgZGVjcmVhc2VzIHRocm91Z2hvdXQgdGhlIENvbGQgV2FyIHRpbWUgcGVyaW9kLiBXaXRoIHRoZSBBeGlzIHBvd2VycywgR2VybWFueeKAmXMgYW5kIEphcGFu4oCZcyBDSU5DIGRyb3BzIG9mZi4KCgpUbyBleHBsb3JlIHRoZSBwYXR0ZXJucyBhYm92ZSwgd2UgY29uc2lkZXJlZCB0aGUgY29tcG9uZW50cyB0aGF0IG1ha2UgdXAgdGhlIENJTkMuIFdlIGNob3NlIHRvIGZvY3VzIG9uIHRoZSBtYWpvciBwb3dlcnMgYmVjYXVzZSB0aGV5IGhhZCB0aGUgbW9zdCBkcmFzdGljIGNoYW5nZXMgZHVyaW5nIHRoaXMgcGVyaW9kLiBXZSBsb29rZWQgYXQgYm90aCB0aGUgYWN0dWFsIHZhbHVlIGFuZCB0aGUgcmF0aW8gYmVjYXVzZSB0aGUgYWJzb2x1dGUgdmFsdWVzIGdyYWR1YWxseSBpbmNyZWFzZWQgb3ZlciB0aW1lIGJ1dCB0aGUgcmF0aW9zIHNob3cgcGVyZm9ybWFuY2UgcmVsYXRpdmUgdG8gdGhlIG90aGVyIGNvdW50cmllcyBlYWNoIHllYXIuIExvb2tpbmcgYXQgdGhlIHJhdGlvcyBoZWxwZWQgdXMgdG8gc2VlIHRyZW5kcyB0aGF0IHdlcmUgbm90IGVhc3kgdG8gc3BvdCB3aGVuIGxvb2tpbmcgYXQgdGhlIG92ZXJhbGwgdmFsdWVzLiBCZWxvdyBpcyBhIHBsb3Qgb2YgZml2ZSBvZiB0aGUgc2l4IENJTkMgY29tcG9uZW50cywgdGhlIHZhbHVlcyBhbmQgdGhlIHJhdGlvcwoKCmBgYHtyIGZpZy53aWR0aD0yNSwgZmlnLmhlaWdodD0yMCAsIGVjaG89RkFMU0V9CgptZXggPC0gZ2dwbG90KCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iWWVhciIpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWU9Ik1pbGl0YXJ5IEV4cGVuZGl0dXJlcyIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcCRtaWxleCksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMSkgKwogIGdlb21fbGluZShkYXRhID0gTk1DX21wLCBhZXMoeCA9IHllYXIsIHkgPSBtaWxleCwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnkpKSArCiAgI2dndGl0bGUoIkNOSUMgYnkgWWVhciBmb3IgTWFqb3IgUG93ZXJzIFRvZGF5IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgptaXA8LSBnZ3Bsb3QoKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJZZWFyIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZT0iTWlsaXRhcnkgUGVyc29ubmVsICIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcCRtaWxwZXIpLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcCwgYWVzKHggPSB5ZWFyLCB5ID0gbWlscGVyLCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsKICAjZ2d0aXRsZSgiQ05JQyBieSBZZWFyIGZvciBNYWpvciBQb3dlcnMgVG9kYXkiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoInNhbG1vbiIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0IiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCm5yZzwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJQcmltYXJ5IEVuZXJneSBDb25zdW1wdGlvbiIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcCRwZWMpLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcCwgYWVzKHggPSB5ZWFyLCB5ID0gcGVjLCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsKICAjZ2d0aXRsZSgiQ05JQyBieSBZZWFyIGZvciBNYWpvciBQb3dlcnMgVG9kYXkiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoInNhbG1vbiIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0IiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCmlhczwtZ2dwbG90KCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iWWVhciIpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWU9Iklyb24gYW5kIFN0ZWVsIFByb2R1Y3Rpb24iKSArCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj14MSwgeG1heD14MiwgeW1pbj0wLCB5bWF4PW1heChOTUNfbXAkaXJzdCksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMSkgKwogIGdlb21fbGluZShkYXRhID0gTk1DX21wLCBhZXMoeCA9IHllYXIsIHkgPSBpcnN0LCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsKICAjZ2d0aXRsZSgiQ05JQyBieSBZZWFyIGZvciBNYWpvciBQb3dlcnMgVG9kYXkiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoInNhbG1vbiIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0IiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCnVycDwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJVcmJhbiBQb3B1bGF0aW9uIikgKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD1tYXgoTk1DX21wJHVwb3ApLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcCwgYWVzKHggPSB5ZWFyLCB5ID0gdXBvcCwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnkpKSArCiAgI2dndGl0bGUoIkNOSUMgYnkgWWVhciBmb3IgTWFqb3IgUG93ZXJzIFRvZGF5IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJub25lIikKCnRvcDwtZ2dwbG90KCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iWWVhciIpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWU9IlRvdGFsIFBvcHVsYXRpb24iKSArCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj14MSwgeG1heD14MiwgeW1pbj0wLCB5bWF4PW1heChOTUNfbXAkdHBvcCksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMTUpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcCwgYWVzKHggPSB5ZWFyLCB5ID0gdHBvcCwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnkpKSArCiAgI2dndGl0bGUoIkNOSUMgYnkgWWVhciBmb3IgTWFqb3IgUG93ZXJzIFRvZGF5IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgojZ3JpZC5hcnJhbmdlKGlhcywgbWV4LCBtaXAsIG5yZywgdXJwLCB0b3AsIG5yb3cgPSAzKQoKCk5NQ19tcF9yYXRpb3MgPC0gZmlsdGVyKE5NQ19yYXRpb3MsIE5NQ19yYXRpb3MkeWVhciAlaW4lIGFsbF95ZWFyKQpOTUNfbXBfcmF0aW9zIDwtIGZpbHRlcihOTUNfcmF0aW9zLCBOTUNfcmF0aW9zJGNjb2RlICVpbiUgY291bnRyeV9jb2RlKQpOTUNfbXBfcmF0aW9zJGNvdW50cnkgPSAiIgpmb3IoIGkgaW4gYygxOmxlbmd0aChjb3VudHJ5X2NvZGUpKSl7CiAgTk1DX21wX3JhdGlvcyRjb3VudHJ5W05NQ19tcF9yYXRpb3MkY2NvZGUgPT0gY291bnRyeV9jb2RlW2ldXSA8LSBjb3VudHJpZXNbaV0KfQoKCm1leF9yPC0gZ2dwbG90KCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iWWVhciIpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWU9Ik1pbGl0YXJ5IEV4cGVuZGl0dXJlcyBSYXRpbyIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcF9yYXRpb3MkbWlsZXgpLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcF9yYXRpb3MsIGFlcyh4ID0geWVhciwgeSA9IG1pbGV4LCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsKICAjZ2d0aXRsZSgiQ05JQyBieSBZZWFyIGZvciBNYWpvciBQb3dlcnMgVG9kYXkiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoInNhbG1vbiIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0IiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKbWlwX3I8LSBnZ3Bsb3QoKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJZZWFyIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZT0iTWlsaXRhcnkgUGVyc29ubmVsIFJhdGlvIikgKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD1tYXgoTk1DX21wX3JhdGlvcyRtaWxwZXIpLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcF9yYXRpb3MsIGFlcyh4ID0geWVhciwgeSA9IG1pbHBlciwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnkpKSArCiAgI2dndGl0bGUoIkNOSUMgYnkgWWVhciBmb3IgTWFqb3IgUG93ZXJzIFRvZGF5IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgpucmdfcjwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJQcmltYXJ5IEVuZXJneSBDb25zdW1wdGlvbiBSYXRpbyIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcF9yYXRpb3MkcGVjKSwgZmlsbD1Db25mbGljdCksYWxwaGE9MC4xKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfbXBfcmF0aW9zLCBhZXMoeCA9IHllYXIsIHkgPSBwZWMsIGNvbG9yID0gY291bnRyeSwgZ3JvdXAgPSBjb3VudHJ5KSkgKwogICNnZ3RpdGxlKCJDTklDIGJ5IFllYXIgZm9yIE1ham9yIFBvd2VycyBUb2RheSIpICsgCiAgdGhlbWVfY2xhc3NpYygpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Yygic2FsbW9uIiwgInBhbGV0dXJxdW9pc2UzIiwgImxpZ2h0c3RlZWxibHVlMiIsICJsaWdodHN0ZWVsYmx1ZTQiLCAibGlnaHRzdGVlbGJsdWUzIiwgInBpbmszIikpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJQYWlyZWQiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpCgoKaWFzX3I8LSBnZ3Bsb3QoKSArIAogIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJZZWFyIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobmFtZT0iSXJvbiBhbmQgU3RlZWwgUHJvZHVjdGlvbiBSYXRpbyIpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KE5NQ19tcF9yYXRpb3MkaXJzdCksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMSkgKwogIGdlb21fbGluZShkYXRhID0gTk1DX21wX3JhdGlvcywgYWVzKHggPSB5ZWFyLCB5ID0gaXJzdCwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnkpKSArCiAgI2dndGl0bGUoIkNOSUMgYnkgWWVhciBmb3IgTWFqb3IgUG93ZXJzIFRvZGF5IikgKyAKICB0aGVtZV9jbGFzc2ljKCkgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkrCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGU9IlBhaXJlZCIpKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSksbGVnZW5kLnBvc2l0aW9uPSJub25lIikKCgp1cnBfcjwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJVcmJhbiBQb3B1bGF0aW9uIFJhdGlvIikgKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD1tYXgoTk1DX21wX3JhdGlvcyR1cG9wKSwgZmlsbD1Db25mbGljdCksYWxwaGE9MC4xKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBOTUNfbXBfcmF0aW9zLCBhZXMoeCA9IHllYXIsIHkgPSB1cG9wLCBjb2xvciA9IGNvdW50cnksIGdyb3VwID0gY291bnRyeSkpICsKICAjZ2d0aXRsZSgiQ05JQyBieSBZZWFyIGZvciBNYWpvciBQb3dlcnMgVG9kYXkiKSArIAogIHRoZW1lX2NsYXNzaWMoKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoInNhbG1vbiIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0IiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIpKSsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZT0iUGFpcmVkIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSxsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKCgp0b3BfcjwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJUb3RhbCBQb3B1bGF0aW9uIFJhdGlvIikgKwogIGxhYnMoY29sb3IgPSdDb3VudHJ5JykrCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj14MSwgeG1heD14MiwgeW1pbj0wLCB5bWF4PW1heChOTUNfbXBfcmF0aW9zJHRwb3ApLCBmaWxsPUNvbmZsaWN0KSxhbHBoYT0wLjEpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19tcF9yYXRpb3MsIGFlcyh4ID0geWVhciwgeSA9IHRwb3AsIGNvbG9yID0gY291bnRyeSwgZ3JvdXAgPSBjb3VudHJ5KSkgKwogICNnZ3RpdGxlKCJDTklDIGJ5IFllYXIgZm9yIE1ham9yIFBvd2VycyBUb2RheSIpICsgCiAgdGhlbWVfY2xhc3NpYygpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Yygic2FsbW9uIiwgInBhbGV0dXJxdW9pc2UzIiwgImxpZ2h0c3RlZWxibHVlMiIsICJsaWdodHN0ZWVsYmx1ZTQiLCAibGlnaHRzdGVlbGJsdWUzIiwgInBpbmszIikpKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlPSJQYWlyZWQiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIixsZWdlbmQua2V5LnNpemUgPSB1bml0KDEsICJjbSIpLCBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9MTApICwgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTApKQogIAoKCmdfbGVnZW5kPC1mdW5jdGlvbihhLmdwbG90KXsKICB0bXAgPC0gZ2dwbG90X2d0YWJsZShnZ3Bsb3RfYnVpbGQoYS5ncGxvdCkpCiAgbGVnIDwtIHdoaWNoKHNhcHBseSh0bXAkZ3JvYnMsIGZ1bmN0aW9uKHgpIHgkbmFtZSkgPT0gImd1aWRlLWJveCIpCiAgbGVnZW5kIDwtIHRtcCRncm9ic1tbbGVnXV0KICByZXR1cm4obGVnZW5kKX0KCm15bGVnZW5kPC1nX2xlZ2VuZCh0b3BfcikKCgojZ3JpZF9hcnJhbmdlX3NoYXJlZF9sZWdlbmQoaWFzLCBpYXNfciwgbWV4LCBtZXhfciwgbWlwLCBtaXBfciwgdXJwLCB1cnBfciwgdG9wLCB0b3BfciwgbnJvdyA9IDYpCgoKYGBgCgoKYGBge3IgZmlnLndpZHRoPTE2LCBmaWcuaGVpZ2h0PTE0fQoKZ3JpZC5hcnJhbmdlKGFycmFuZ2VHcm9iKGlhcywgaWFzX3IsIG1leCwgbWV4X3IsIG1pcCwgbWlwX3IgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpLCBsZWdlbmQucG9zaXRpb249Im5vbmUiKSxucm93PTMsIG5jb2wgPTIpLG15bGVnZW5kLCBoZWlnaHRzPWMoMTAsMSkpCgojZ3JpZC5hcnJhbmdlKGlhcywgaWFzX3IsIG1leCwgbWV4X3IsIG1pcCwgbWlwX3IsIHVycCwgdXJwX3IsIHRvcCwgdG9wX3IsIG5yb3c9NikKYGBgCgoKV2l0aCB0aGUgSXJvbiBhbmQgU3RlZWwgUHJvZHVjdGlvbiByYXRpbywgeW91IGNhbiBzZWUgdGhhdCBpdCBmb2xsb3dzIHRvIHNhbWUgcGF0dGVybiBhcyB0aGUgQ0lOQyBmb3IgdGhlIFVTIGR1cmluZyB0aGlzIHBlcmlvZC4gVGhlIHJhdGlvIHBlYWtzIHRvd2FyZHMgdGhlIGVuZCBvZiBXV0kgYW5kIFdXSUkgYW5kIGRlY3JlYXNlcyBpbiB0aGUgcGVyaW9kIGJldHdlZW4gdGhlIHR3byB3YXJzLiBUaWxsIGFib3V0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIFZpZXRuYW0gV2FyLCByb3VnaGx5IDE5NTUsIHRoZSBVUyBkb21pbmF0ZWQgdGhlIHdvcmxkIGluIElyb24gYW5kIFN0ZWVsIHByb2R1Y3Rpb24gYW5kIHNvIHRoaXMgdmFsdWUgaGFkIGh1Z2UgaW1wYWN0IHRoZSBVU+KAmXMgQ0lOQyBzY29yZS4gR2VuZXJhbGx5LCBkdXJpbmcgbW9zdCB3YXJzLCB0aGUgVVMgaGFzIHRoZSBtb3N0IG1pbGl0YXJ5IHByb2R1Y3Rpb24gYnV0IGxvc3QgaXRzIHBvc2l0aW9uIHRvd2FyZCBzIHRoZSBlbmQgb2YgdGhlIFZpZXRuYW0gd2FyIHdoZW4gUnVzc2lhIHN1cnBhc3NlZCB0aGUgVVMuIFRoZSBVbml0ZWQgS2luZ2RvbSBtYWludGFpbmVkIGl0cyBpcm9uIGFuZCBzdGVlbCBwcm9kdWN0aW9uLCBidXQgc2luY2UgVVNBIGFuZCBSdXNzaWEgd2VyZSBpbmNyZWFzaW5nIHRoZWlyIHByb2R1Y3Rpb24sIHRoZSBVS3MgcmF0aW8gaGFzIGJlZW4gc3RlYWRpbHkgZGVjcmVhc2luZyBzaW5jZSB0aGUgMTkwMHMsIHZlcnkgc2ltaWxhciB0byB0aGF0IG9mIHRoZSBwYXR0ZXJuIG9ic2VydmVkIHdpdGggdGhlIENJTkMgc2NvcmUuIAoKTG9va2luZyBhdCBtaWxpdGFyeSBleHBlbmRpdHVyZSB3ZSBzZWUgdGhhdCB0aGUgVVMgYW5kIFJ1c3NpYSBoYWQgYmVlbiBzaWduaWZpY2FudGx5IGludmVzdGluZyBtb3JlIGluIHRoZSBtaWxpdGFyeSB0aHJvdWdob3V0IHRoZSBjb2xkIHdhci4gT24gdGhlIG90aGVyIGhhbmQsIGJvdGggY291bnRyaWVzIGRlY3JlYXNlIHRoZWlyIG1pbGl0YXJ5IHBlcnNvbm5lbCBhZnRlciB0aGV5IHBlYWtlZCBhdCB0aGUgZW5kIG9mIFdXSUkuIFRoZXNlIGZpbmRpbmdzIGFyZSBjb25zaXN0ZW50IHdpdGggdGhlIENvbGQgV2FyIHdoZXJlIHRoZSBVUyBhbmQgUnVzc2lhIHdlcmUgaW4gYW4gYXJtcyByYWNlIHdoZXJlIHRoZXkgaGVhdmlseSBpbnZlc3RlZCBpbiBtaWxpdGFyeSB0ZWNobm9sb2d5IGJ1dCBkaWQgbm90IGVuZ2FnZSBpbiBhbnkgbGFyZ2Utc2NhbGUgYmF0dGxlcy4gVGhlIFVT4oCZcyBtaWxpdGFyeSBleHBlbmRpdHVyZXMgcmF0aW8gcGVha3MgdGhlIHNhbWUgeWVhciBpdHMgQ0lOQyBzY29yZSBhbmQgaXJvbiBhbmQgc3RlZWwgcHJvZHVjdGlvbiByYXRpby4KCkluIHRoZSBmZXcgeWVhcnMgYmVmb3JlIFdXSUksIHlvdSBzZWUgR2VybWFueeKAmXMgbWlsaXRhcnkgZXhwZW5kaXR1cmVzIHJhdGlvIGluY3JlYXNlIHF1aXRlIHJhcGlkbHkgYW5kIHRoZSBtaWxpdGFyeSBwZXJzb25uZWwgcmF0aW8gc2F3IGEgZHJhc3RpYyBpbmNyZWFzZSBpbiB0aGUgb25lIHllYXIgYmVmb3JlIGluY3JlYXNpbmcgcXVpdGUgcmFwaWRseS4gQWx0aG91Z2ggbm90IGFzIGRyYXN0aWMsIEphcGFuIGFuZCBDaGluYSBmb2xsb3cgYSBzaW1pbGFyIHBhdHRlcm4gd2hlcmUgdGhlIG1pbGl0YXJ5IGludmVzdG1lbnQgaW5jcmVhc2VkIHNpZ25pZmljYW50bHkgYSBmZXcgeWVhcnMgcHJpb3IgdG8gV1dJSSBhbmQgdGhlIEtvcmVhbiBXYXIsIHJlc3BlY3RpdmVseSwgYW5kIHRoZSBtaWxpdGFyeSBwZXJzb25uZWwgcmF0aW8gZHJhc3RpY2FsbHkgaW5jcmVhc2VkIHJpZ2h0IGJlZm9yZSB0aGUgd2Fycy4gVGhpcyBzdWdnZXN0cyB0aGF0IGluIHllYXJzIGJlZm9yZSB0aGUgd2FycywgdGhlc2UgY291bnRyaWVzIHN0YXJ0ZWQgaW52ZXN0aW5nIGluIGFuZCBwcmVwYXJpbmcgdGhlaXIgbWlsaXRhcmllcyBmb3Igd2FyLiBUaGUgY291bnRyaWVzIHRoYXQgd2VyZSBvbiB0aGUgcmVhY3RpdmUgc2lkZSwgdGhlIFVTLCBSdXNzaWEgYW5kIHRoZSBVSywgdGhlaXIgbWlsaXRhcnkgcHJvZHVjdGlvbiByYXRpb3MgYW5kIG1pbGl0YXJ5IGV4cGVuZGl0dXJlcyByYXRpb3Mgb25seSBpbmNyZWFzZWQgZHVyaW5nIHRoZSB3YXIuIAoKCmBgYHtyIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0zfQpOTUNfdjwtIGZpbHRlcihOTUNfcmF0aW9zLCBOTUNfcmF0aW9zJHllYXIgJWluJSBjKDE5NzA6MjAwMCkpCk5NQ19yYXRpb3NfdjwtIGZpbHRlcihOTUNfcmF0aW9zLCBOTUNfcmF0aW9zJHllYXIgJWluJSBjKDE5NzA6MjAwMCkpCiNuYW1lcyA8LSBjKCJOb3J0aCBLb3JlYSIsICJTb3V0aCBLb3JlYSIsICJBZmdoYW5pc3RhbiIgICwgIlZpZXRuYW0iLCAiUmVwdWJsaWMgb2YgVmlldG5hbSIpCiNjb2RlPC0gYyg3MzEsIDczMiw3MDAsIDgxNiwgODE3KQpuYW1lcyA8LSBjKCJJcmFxIikKY29kZSA8LSBjKDY0NSkKTk1DX3Y8LSBmaWx0ZXIoTk1DX3YsIE5NQ192JGNjb2RlICVpbiUgY29kZSkKTk1DX3JhdGlvc192PC0gZmlsdGVyKE5NQ19yYXRpb3NfdiwgTk1DX3JhdGlvc192JGNjb2RlICVpbiUgY29kZSkKZm9yKCBpIGluIGMoMTpsZW5ndGgoY29kZSkpKXsKICBOTUNfcmF0aW9zX3YkY291bnRyeVtOTUNfcmF0aW9zX3YkY2NvZGUgPT0gY29kZVtpXSBdPC0gbmFtZXNbaV0KICBOTUNfdiRjb3VudHJ5W05NQ192JGNjb2RlID09IGNvZGVbaV0gXTwtIG5hbWVzW2ldCn0KCgphPC0gZ2dwbG90KCkgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMobmFtZT0iWWVhciIpICsgCiAgc2NhbGVfeV9jb250aW51b3VzKG5hbWU9IlJhdGlvIikgKyAKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19yYXRpb3NfdiwgYWVzKHggPSB5ZWFyLCB5ID0gbWlsZXgpLCBjb2xvdXIgPSAiaW5kaWFucmVkMyIpICsKICBnZ3RpdGxlKCJJcmFxIE1pbGl0YXJ5IEV4cGVuZGl0dXJlcyBSYXRpbyIpICsgCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj0xOTkwLCB4bWF4PTE5OTEsIHltaW49MCwgeW1heD0uMDI1KSxhbHBoYT0wLjAzKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUsIHNpemUgPTEwICksICAgYXhpcy50ZXh0LnggPWVsZW1lbnRfdGV4dChzaXplID02KSwgYXhpcy50ZXh0LnkgPWVsZW1lbnRfdGV4dChzaXplID02KSwgYXhpcy50aXRsZS54ID1lbGVtZW50X3RleHQoc2l6ZSA9OCksIGF4aXMudGl0bGUueSA9ZWxlbWVudF90ZXh0KHNpemUgPTgpLCBsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKYjwtIGdncGxvdCgpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKG5hbWU9IlllYXIiKSArIAogIHNjYWxlX3lfY29udGludW91cyhuYW1lPSJSYXRpbyIpICsKICBnZW9tX2xpbmUoZGF0YSA9IE5NQ19yYXRpb3NfdiwgYWVzKHggPSB5ZWFyLCB5ID0gbWlscGVyKSwgY29sb3VyPSAicm95YWxibHVlMyIpICsKICBnZ3RpdGxlKCJJcmFxIE1pbGl0YXJ5IFBlcnNvbm5lbCBSYXRpbyIpICsgCiAgZ2VvbV9yZWN0KGRhdGE9ZCwgbWFwcGluZz1hZXMoeG1pbj0xOTkwLCB4bWF4PTE5OTEsIHltaW49MCwgeW1heD0uMDUpLCBhbHBoYT0wLjAzKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUsIHNpemUgPTEwICksICAgYXhpcy50ZXh0LnggPWVsZW1lbnRfdGV4dChzaXplID02KSwgYXhpcy50ZXh0LnkgPWVsZW1lbnRfdGV4dChzaXplID02KSwgYXhpcy50aXRsZS54ID1lbGVtZW50X3RleHQoc2l6ZSA9OCksIGF4aXMudGl0bGUueSA9ZWxlbWVudF90ZXh0KHNpemUgPTgpLCBsZWdlbmQucG9zaXRpb249Im5vbmUiKQoKZ3JpZC5hcnJhbmdlKGEsYixucm93ID0gMSkKYGBgCgpXZSB3YW50ZWQgdG8gc2VlIGlmIHRoaXMgdGhpcyBzYW1lIHBhdHRlcm4gd2FzIHByZXNlbnQgaW4gb3RoZXIgY29uZmxpY3RzLiBEdXJpbmcgdGhlIEd1bGYgV2FyLCBJcmFxIGludmFkZWQgS3V3YWl0IGFuZCBpdCB3YXMgbWV0IHdpdGggaW50ZXJuYXRpb25hbCBjb25kZW1uYXRpb24gYW5kIHRoZSBVUyBhbmQgb3RoZXIgbmF0aW9ucyBqb2luZWQgZm9yY2VzIHRvIHN0b3AgSXJhcSAoUGVyc2lhbiBHdWxmIFdhcikuIEJ1dCBiZWZvcmUgdGhlIGludmFzaW9uIGluIHdhciB3ZSBzZWUgSXJhceKAmXMgbWlsaXRhcnkgZXhwZW5kaXR1cmVzIGFuZCBwZXJzb25uZWwgcmF0aW9zIGluY3JlYXNpbmcuIFRoZSBncmF5IHNoYWRlZCBib3ggaW5kaWNhdGVzIHRoZSBwZXJpb2Qgb2YgdGhlIEd1bGYgV2FyICgxOTkwLTE5OTEpLiBJbiB0aGUgMTk4MHMsIElyYXHigJlzIG1pbGl0YXJ5IGV4cGVuZGl0dXJlIHJhdGlvIGRyYXN0aWNhbGx5IGluY3JlYXNlZCBhbmQgdGhlbiB0aGVyZSB3YXMgYSBzdWRkZW4gc3Bpa2UgaW4gbWlsaXRhcnkgcGVyc29ubmVsIHJpZ2h0IGJlZm9yZSB0aGUgc3RhcnQgb2YgdGhlIHdhci4gIAoKYGBge3IgZmlnLndpZHRoPTE0LCBmaWcuaGVpZ2h0PTZ9CmN0IDwtIGMoIlVuaXRlZCBTdGF0ZXMgb2YgQW1lcmljYSIsICJVbml0ZWQgS2luZ2RvbSIsICJGcmFuY2UiLCAiUnVzc2lhIiwiR2VybWFueSIsICJJdGFseSIsICJKYXBhbiIsICJDaGluYSIpCmN0X2Njb2RlIDwtIG1lbWJlcl9hbGxpYW5jZXMkY2NvZGVbbWF0Y2goY3QsIG1lbWJlcl9hbGxpYW5jZXMkc3RhdGVfbmFtZSldCgpOTUNfY3QgPC0gZmlsdGVyKE5NQywgTk1DJHllYXIgJWluJSBhbGxfeWVhcikKTk1DX2N0IDwtIGZpbHRlcihOTUNfY3QsIE5NQ19jdCRjY29kZSAlaW4lIGN0X2Njb2RlKQpmb3IoIGkgaW4gYygxOmxlbmd0aChjdF9jY29kZSkpKXsKICBOTUNfY3QkY291bnRyeVtOTUNfY3QkY2NvZGUgPT0gY3RfY2NvZGVbaV1dIDwtIGN0W2ldCn0KCmE8LSBnZ3Bsb3QoTk1DX2N0LCBhZXMoY291bnRyeSwgeWVhciwgZmlsbCA9IGNpbmMpKSArIGdlb21fdGlsZSgpKwogIHhsYWIoIkNvdW50cnkiKSArCiAgeWxhYigiWWVhciIpICsKICBzY2FsZV9maWxsX3ZpcmlkaXMoKSArIAogIGdndGl0bGUoIkNJTkMgSGVhdG1hcCBmb3IgTWFqb3IgUG93ZXJzIikgKyAKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKyAKICBjb29yZF9mbGlwKCkgKwogIGxhYnMoY29sb3IgPSdDSU5DJykKCgp0b3BDYXMgPC0gYygiTmV0aGVybGFuZHMiLCAiWXVnb3NsYXZpYSIsICJMaXRodWFuaWEiLCAiUG9sYW5kIiwgIkF1c3RyaWEiLCAiSHVuZ2FyeSIsICJSb21hbmlhIiwgIkVzdG9uaWEiLCAiTHV4ZW1ib3VyZyIpCnRvcENhc19jY29kZSA8LSBtZW1iZXJfYWxsaWFuY2VzJGNjb2RlW21hdGNoKHRvcENhcywgbWVtYmVyX2FsbGlhbmNlcyRzdGF0ZV9uYW1lKV0KCgpOTUNfY2FzIDwtIGZpbHRlcihOTUNfb3JpZywgTk1DJHllYXIgJWluJSBhbGxfeWVhcikKTk1DX2NhcyA8LSBmaWx0ZXIoTk1DX2NhcywgTk1DX2NhcyRjY29kZSAlaW4lIHRvcENhc19jY29kZSkKZm9yKCBpIGluIGMoMTpsZW5ndGgodG9wQ2FzX2Njb2RlKSkpewogIE5NQ19jYXMkY291bnRyeVtOTUNfY2FzJGNjb2RlID09IHRvcENhc19jY29kZVtpXV0gPC0gdG9wQ2FzW2ldCn0KCmI8LSBnZ3Bsb3QoTk1DX2NhcywgYWVzKGNvdW50cnksIHllYXIsIGZpbGwgPSBjaW5jKSkgKyBnZW9tX3RpbGUoKSsKICB4bGFiKCJDb3VudHJ5IikgKwogIHlsYWIoIlllYXIiKSArCiAgc2NhbGVfZmlsbF92aXJpZGlzKCkgKyAKICBnZ3RpdGxlKCJDSU5DIEhlYXRtYXAgZm9yIENvdW50cmllcyB3aXRoIHRoZSBtb3N0IEhvbG9jYXVzdCBDYXN1YWx0aWVzIikgKyAKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpICsKICBjb29yZF9mbGlwKCkgKwogIGxhYnMoY29sb3IgPSdDSU5DJykKICAKCmdyaWQuYXJyYW5nZShhLGIsIG5yb3cgPSAxICkKYGBgCgpGaW5hbGx5LCB1c2luZyB0aGUgaGVhdCBtYXBzLCB3ZSBsb29rZWQgYXQgaW1wYWN0IG9uIENJTkMgYWZ0ZXIgYSB3YXIuIE9uIHRoZSBsZWZ0IGlzIGEgaGVhdCBtYXAgb2YgdGhlIG1ham9yIHBvd2Vycy4gWW91IGNhbiBzZWUgdGhhdCBGcmFuY2UsIEdlcm1hbnkgYW5kIEphcGFuIGhhZCBtaXNzaW5nIENJTkMgdmFsdWVzIGF0IHRoZSBlbmQgb2YgV29ybGQgV2FyIElJLiBUaG9zZSBwZXJpb2RzIG9mIG1pc3NpbmcgdmFsdWVzIGNvcnJlc3BvbmQgdG8gdGhlIHJlY292ZXJ5IHBlcmlvZCBmb3IgZWFjaCBvZiB0aG9zZSBjb3VudHJpZXMgZm9sbG93aW5nIHRoZSB3YXIuIE5leHQsIHdlIGxvb2tlZCB0byBzZWUgd2hhdCBvdGhlciBjb3VudHJpZXMgaGFkIGdhcHMgaW4gdGhlaXIgQ0lOQyBkYXRhLiBNb3N0IG9mIHRoZSBjb3VudHJpZXMgdGhhdCBoYXZlIG1pc3NpbmcgZ2FwcyBhcmUgRWFzdGVybiBFdXJvcGVhbiBjb3VudHJpZXMgdGhhdCB3aGVyZSBoZWF2aWx5IGltcGFjdGVkIGJ5IHRoZSBIb2xvY2F1c3QgYW5kIGJ5IHRoZSBzdHJ1Z2dsZSB0byBlbmQgQ29tbXVuaXNtIGluIHRoZSByZWdpb24gKFJveWRlLVNtaXRoKS4gVGhpcyBpbmRpY2F0ZXMgdGhhdCBmb3IgY291bnRyaWVzIHRoYXQgYXJlIGdvaW5nIHRocm91Z2ggaW50ZW5zZSBkZXN0cnVjdGlvbiBvciByZWZvcm1hdGlvbiwgdGhleSBkbyBub3QgaGF2ZSBhbnkgQ0lOQyBpbmZvcm1hdGlvbi4KCgoqKkNvbmNsdXNpb25zICYgTmV4dCBTdGVwcyAqKgoKVG8gZ2V0IGV2ZW4gbW9yZSBpbnRvIGRldGFpbCBhbmQgY29udGV4dCBhcm91bmQgY2VydGFpbiBjaGFyYWN0ZXJpc3RpY3MsIHdlIHdhbnQgdG8gbG9vayBhdCBzcGVjaWZpYyBldmVudHMgbGlrZSBwZWFybCBoYXJib3Igb3IgQ2hpbmHigJlzIGludmFzaW9uIG9mIE1hbGF5c2lhIGFuZCBvdGhlciBwaXZvdGFsIG1vbWVudHMgaW4gd2FycyB0byBzZWUgaG93IHRob3NlIGV2ZW50cyBpbXBhY3QgdGhlIENJTkMgYW5kIGl0cyB2YXJpb3VzIGNvbXBvbmVudHMuICAKCkEgcHJvYmxlbSB3aXRoIE5NQyBpcyB0aGF0IHRoZXJlIGFyZSBtYW55IG90aGVyIGZhY3RvcnMgdGhhdCBkZXRlcm1pbmUgYSBwb3dlciBvZiBhIG5hdGlvbiByYXRoZXIgdGhhbiB0aGUgNiBOTUMgZmFjdG9ycy4gT25lIG9mIHRoZSBtYWpvciBjb25zaWRlcmF0aW9ucyB0aGF0IGlzIG5vdCBjb25zaWRlcmVkIGlzIHRoZSBkaXBsb21hdGljIHJlbGF0aW9uIGJldHdlZW4gY291bnRyaWVzLiBEaXBsb21hdGljIHJlbGF0aW9ucyBwbGF5IGEgbWFqb3Igcm9sZSBpcyB0aGUgcHJldmVudGlvbiBhbmQgY29uY2x1c2lvbiBvZiBjb25mbGljdHMuIFdpdGggdGhpcyBkYXRhLCBpdCB3YXMgbm90IHBvc3NpYmxlIHRvIGZhY3RvciB0aGF0IGluLiAKCkFkZGl0aW9uYWxseSwgYW5vdGhlciB0aGluZyB0byBjb25zaWRlciBpcyBkaWZmZXJlbmNlcyBpbiBwb2xpY2llcyBiZXR3ZWVuIGRpZmZlcmVudCBjb3VudHJpZXMuIFdlIHNlZSB0aGF0IG1pbGl0YXJ5IGV4cGVuZGl0dXJlcyBoYXZlIGJlZW4gaW5jcmVhc2luZyBmb3IgdGhlIFVTIHNpbmNlIHRoZSBDb2xkIFdhciBidXQgUnVzc2lh4oCZcyBtaWxpdGFyeSBleHBlbmRpdHVyZXMgdGFrZSBhIHN1ZGRlbiBkcm9wIGF0IHRoZSBlbmQgb2YgdGhlIENvbGQgV2FyLiBTaW5jZSB0aGUgZW5kIG9mIHRoZSBDb2xkIFdhciwgUnVzc2lhIGhhcyBiZWVuIGN1dHRpbmcgbWlsaXRhcnkgc3BlbmRpbmcgdGlsbCB0b2RheSAoUm95ZGUtU21pdGgpLiBFdmVuIHdpdGggaXRzIHBhcnRpY2lwYXRpb24gaW4gdGhlIEFmZ2hhbmlzdGFuIFdhciwgUnVzc2lh4oCZcyBtaWxpdGFyeSBleHBlbmRpdHVyZXMgaGF2ZSBub3QgaW5jcmVhc2VkLiBPbiB0aGUgY29udHJhcnksIGluIHRoZSBVUyB0b2RheSwgcG9saXRpY2lhbnMgYXJlIHByb3Bvc2luZyBhIEZlZGVyYWwgQnVkZ2V0cyB3aXRoIGluY3JlYXNlcyBpbiBtaWxpdGFyeSBzcGVuZGluZy4gVGhpcyBkaWZmZXJlbmNlIGlzIGR1ZSB0byBkaWZmZXJlbmNlcyBpbiBwb2xpY2llcyBvZiB0aGUgY291bnRyaWVzLiBUaHVzLCB0aGUgcmVhY3Rpb25zIG9mIGNvdW50cmllcyB0byBldmVudHMgd2lsbCBkcmFzdGljYWxseSB2YXJ5IGJhc2VkIG9uIHRoZWlyIHBvbGljaWVzIGFuZCBpdCBiZWNhdXNlIGhhcmQgdG8gZGlzdGluZ3Vpc2ggYW4gb3ZlcmFsbCBwYXR0ZXJuLiAKCkFub3RoZXIgZHJhd2JhY2sgb2YgTk1DIGlzIHRoYXQgaXQgY2Fubm90IGNvbnNpZGVyIGNoYW5nZXMgaW4gdW5pdmVyc2FsIHByaW9yaXRpZXMuIEZvciBleGFtcGxlLCB3aXRoIGFuIGluY3JlYXNlZCBjb25jZXJuIGZvciBjbGltYXRlIGNoYW5nZSBhbmQgc2NhcmUgbmF0dXJhbCByZXNvdXJjZXMgYW5kIHdpdGggYWR2YW5jZW1lbnRzIGluIHRlY2hub2xvZ3ksIGlyb24gYW5kIHN0ZWVsIHByb2R1Y3Rpb24gbWlnaHQgc3RhcnQgdG8gZGVjcmVhc2UgZHJhc3RpY2FsbHkgaW4gdGhlIGZ1dHVyZSBzbyBpdCBtYXkgbm8gbG9uZ2VyIGJlIGEgdmFsaWQgbWVhc3VyZSBvZiBwb3dlci4gIFNpbWlsYXJseSwgYWR2YW5jZW1lbnRzIGluIHRlY2hub2xvZ3kgd291bGQgZGVjcmVhc2UgdGhlIG5lZWQgZm9yIG1pbGl0YXJ5IHBlcnNvbm5lbC4gVGhlIGlzc3VlIHdpdGggTk1DIGlzIHRoYXQgaXQgY2Fubm90IHRha2Ugc3VjaCBwb2xpY3kgY29uY2VybnMgYW5kIGNoYW5nZXMgaW50byBjb25zaWRlcmF0aW9uIHRvIG1lYXN1cmUgbmF0aW9uYWwgcG93ZXIuIAoKCgoKIyMjI0FsbGlhbmNlcwoKCmBgYHtyIGZpZy53aWR0aD0xNCwgZmlnLmhlaWdodD04fQoKZGF5ZF9hbF95ZWFyIDwtIGZpbHRlcihkeWFkX2FsX3llYXIsIGR5YWRfYWxfeWVhciR5ZWFyICVpbiUgYygxOTAwOjIwMTIpKQpkeWFkX2FsX3llYXIkbGVuZ3RoID0gZHlhZF9hbF95ZWFyJGR5YWRfZW5kX3llYXIgLSBkeWFkX2FsX3llYXIkZHlhZF9zdF95ZWFyCgpkYXlkX2FsX3llYXIkY29uZmxpY3QgPC0gIjAiCmR5YWRfYWxfeWVhciRjb3VudCA8LSAxIAoKZGlyX2FsbGlhbmNlcyA8LSBnYXRoZXIoZGlyX2FsX3llYXIsIHRyZWF0eV90eXBlLCBpZGljYXRvciwgZGVmZW5zZTplbnRlbnRlKQpkaXJfYWxsaWFuY2VzIDwtIGRpcl9hbGxpYW5jZXNbIWRpcl9hbGxpYW5jZXMkaWRpY2F0b3IgJWluJSAgMCxdCmRpcl9hbGxpYW5jZXMkZHlhZF9lbmRfeWVhcltkaXJfYWxsaWFuY2VzJGR5YWRfZW5kX3llYXIgJWluJSBOQV0gPSAyMDE2CmRpcl9hbGxpYW5jZXMgPC0gZGlyX2FsbGlhbmNlc1tkaXJfYWxsaWFuY2VzJHllYXI+MTkwMCxdCmFsbGlhbmNlX2NvdW50IDwtIGRpcl9hbGxpYW5jZXNbLCBjKDIsMywxNCwxNildCmFsbGlhbmNlX2NvdW50JGNvdW50IDwtIDEgCgpncF9jdCA8LSBhZ2dyZWdhdGUoY2JpbmQoY291bnQpIH4gY2NvZGUxK3N0YXRlX25hbWUxK3llYXIrdHJlYXR5X3R5cGUsIGRhdGEgPWFsbGlhbmNlX2NvdW50LCBGVU4gPSBzdW0gKQpncF9jdCRDb25mbGljdCA8LSAiMCIKCmZvcihpIGluIGMoMTpsZW5ndGgoZCR4MSkpKXsKICBncF9jdFtncF9jdCR5ZWFyID49IGQkeDFbaV0gJiBncF9jdCR5ZWFyIDw9IGQkeDJbaV0sIGxlbmd0aChncF9jdCldIDwtIGFzLmNoYXJhY3RlcihpKQp9CgpgYGAKCgpXV0kgd2FzIHRyaWdnZXJlZCBieSB0aGUgYXNzYXNzaW5hdGlvbiBvZiB0aGUgQXJjaGR1a2UgRnJhbnogRmVyZGluYW5kIG9mIEF1c3RyaWEuIEhpcyBkZWF0aCBzZXQgb2ZmIGRpcGxvbWF0aWMgY3Jpc2lzIGFzIGNvdW50cmllcyB0aGF0IHdlcmUgbm90IGludm9sdmVkIGluIHRoZSBvcmlnaW5hbCBjb25mbGljdCB3ZXJlIGZvcmNlZCB0byBnZXQgaW52b2x2ZWQuIE9uY2UgQXVzdHJpYSBkZWNsYXJlZCB3YXIgb24gU2VyYmlhIGZvciB0aGUgZGVhdGggb2YgdGhlIEFyY2ggRHVrZSwgUnVzc2lhIGhhZCB0byBzdGVwIGludG8gZGVmZW5kIFNlcmJpYS4gT25jZSBSdXNzaWEgZW50ZXJlZCB0aGUgY29uZmxpY3QsIEdlcm1hbnkgd2FzIGZvcmNlZCB0byBlbnRlciB0aGUgY29uZmxpY3QgZHVlIHRvIGl0cyBhbGxpYW5jZSB3aXRoIEF1c3RyaWEuIER1cmluZyB0aGUgY29uZmxpY3QgR2VybWFueSBpbnZhZGVkIEJlbGdpdW07IGluIHJlc3BvbnNlLCB0aGUgVW5pdGVkIEtpbmdkb20gbW9iaWxpemVkIGR1ZSB0byB0aGVpciBhbGxpYW5jZSB3aXRoIEJlbGdpdW0uIFRoaXMgcGF0dGVybiBjb250aW51ZWQgdG8gZXZlbnR1YWxseSBpbnZvbHZlIGFsbCB0aGUgbWFqb3IgcG93ZXJzIG9mIHRoZSB3b3JsZCBmb3IgYSBkZXZhc3RhdGluZyBiYXR0bGUuIFN1Y2ggYWxsaWFuY2VzIHdlcmUgdGhlIGNhdXNlIG9mIFdvcmxkIFdhciBJLiBTaW5jZSB0aGVuIHRoZSBudW1iZXIgb2YgQWxsaWFuY2VzIGhhcyBvbmx5IGdyb3duIGFuZCBjb250aW51ZXMgdG8gZ3Jvdy4gRm9yIHRoaXMgcmVhc29uLCB3ZSB3YW50ZWQgdG8gbG9vayBhdCBhbGxpYW5jZXMgYW5kIHNlZSBob3cgdGhleSBjaGFuZ2UgZHVyaW5nIHdhcnMuIAoKQmVsb3cgaXMgYm94cGxvdCBvZiB0aGUgdG90YWwgbnVtYmVyIG9mIGFsbGlhbmNlcyB0aGF0IGFyZSBpbiBlZmZlY3QgZWFjaCB5ZWFyIGJldHdlZW4gYW55IHR3byBjb3VudHJpZXMuIEl0IGlzIGVhc3kgdG8gc2VlIHRoYXQgdGhlIG1lZGlhbiBudW1iZXIgb2YgYWxsaWFuY2VzIGp1bXBlZCB1cCBzaWduaWZpY2FudGx5IGR1cmluZyBXV0lJIGFuZCBjb250aW51ZWQgdG8gZ3JvdyBkdXJpbmcgdGhlIENvbGQgV2FyIGFuZCByZW1haW5lZCByZWxhdGl2ZWx5IGxldmVsIHNpbmNlIHRoZW4uIEFuIGludGVyZXN0aW5nIHBhdHRlcm4gaXMgdGhhdCB0aGUgbWVkaWFuIG51bWJlciBvZiBhbGxpYW5jZXMgaW5jcmVhc2VkIG1vcmUgaW4gdGhlIDEtMyBiZWZvcmUgdGhlIGVuZCBvZiB3YXIuIFlvdSBjYW4gc2VlIHRoaXMgcGF0dGVybiB3aXRoIFdXSSwgS29yZWFuIFdhciwgVmlldG5hbSBXYXIgYW5kIHRoZSBlbmQgb2YgdGhlIENvbGQgV2FyLiBBbHRob3VnaCB0aGUgQ29sZCBXYXIgd2FzIG9ubHkgYSBzdGF0ZSBvZiBzZXZlcmUgcG9saXRpY2FsIHdhciB0aGVyZSB3ZXJlIG1hbnkgcmVnaW9uYWwgYmF0dGxlcyBhbmQgdGhlIHRocmVhdCBvZiBhIGxhcmdlLXNjYWxlIG1pbGl0YXJ5IHdhciB3YXMgY29uc3RhbnQuIFRoZSBudW1iZXIgb2YgYWxsaWFuY2VzIHNpZ25pZmljYW50bHkgaW5jcmVhc2VkIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBDb2xkIFdhciB0aWxsIHRoZSBlbmQuICAKCgpgYGB7ciBmaWcud2lkdGg9MjAsIGZpZy5oZWlnaHQ9OH0KZ2dwbG90KCkgKwogIHhsYWIoIlllYXIiKSArCiAgeWxhYigiQ291bnQiKSsKICBnZW9tX2JveHBsb3QoZGF0YSA9IGdwX2N0LCBhZXMoeCA9IGFzLmZhY3Rvcih5ZWFyKSwgeSA9IGNvdW50LCBmaWxsID0gQ29uZmxpY3QpKSArCiAgZ2d0aXRsZSgiVG90YWwgQWxsaWFuY2VzIGJ5IFllYXIiKSArIAogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUsIHNpemUgPSAyMCksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHNpemUgPSAxMCksICBheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLCAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSwgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPTE1KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzPWMoIndoaXRlIiwgImxpZ2h0c3RlZWxibHVlMyIsICJwaW5rMyIsICJwYWxldHVycXVvaXNlMyIsICJsaWdodHN0ZWVsYmx1ZTIiLCAibGlnaHRzdGVlbGJsdWU0Iiwic2FsbW9uIiApLCBsYWJlbHMgPSBteWxhYmxlcykKCmBgYApOZXh0IHdlIGxvb2tlZCBhdCB0aGUgdHlwZXMgb2YgYWxsaWFuY2VzIGZvcm1lZCBkdXJpbmcgdGhpcyB0aW1lLiBUaGUgQ09XIGRhdGEgcmVwb3J0cyBvbiA0IHR5cGVzIG9mIGFsbGlhbmNlczogZGVmZW5zZSwgbmV1dHJhbGl0eSwgZW50ZW50ZSBhbmQgbm9uLWFnZ3Jlc3Npb24uIEluIGEgZGVmZW5zZSBhbGxpYW5jZSwgdGhlIG1lbWJlciBzdGF0ZXMgYWdyZWUgdG8gZGVmZW5kIG9uZSBvciBtb3JlIHN0YXRlcyBpbiBhbGxpYW5jZSBpbiB0aGUgZXZlbnQgb2YgYSBjb25mbGljdC4gV2l0aCBhIG5ldXRyYWxpdHkgYWxsaWFuY2UsIHRoZXJlIGlzIGFuIGFncmVlbWVudCB0byBtYWludGFpbiBuZXV0cmFsaXR5IHRvd2FyZHMgdGhlIG1lbWJlcnMgb2YgdGhlIGFsbGlhbmNlLiBJbiBub24tYWdncmVzc2lvbiBhbGxpYW5jZSwgdGhlIG1lbWJlcnMgYWdyZWUgdG8gdGFrZSBubyBtaWxpdGFyeSBhY3Rpb24gYWdhaW5zdCBvbmUgYW5vdGhlci4gRmluYWxseSwgd2l0aCBhbiBlbnRlbnRlIGFsbGlhbmNlIHRoZXJlIGlzIGFuIHVuZGVyc3RhbmRpbmcgdGhhdCB0aGUgc3RhdGVzIHdvdWxkIGNvbnN1bHQgd2l0aCBvbmUgYW5vdGhlciBpZiBhIGNyaXNpcyBvY2N1cnJlZCAoRm9ybWFsIEFsbGlhbmNlcykuIAoKVGhlIHBsb3RzIGJlbG93IHNob3cgdGhlIG51bWJlciBvZiBhbGxpYW5jZXMgYnkgYWxsaWFuY2UgdHlwZS4gVGhlIHRvcCByb3cgc2hvd3MgdGhlIG51bWJlciBvZiBuZXcgYWxsaWFuY2VzIHRoYXQgd2VyZSBmb3JtZWQgZWFjaCB5ZWFyIGFuZCB0aGUgc2Vjb25kIHJvdyBzaG93cyBudW1iZXIgb2YgYWxsaWFuY2VzIHRoYXQgd2VyZSB0ZXJtaW5hdGVkIHRoYXQgeWVhci4gUGxlYXNlIG5vdGUgdGhhdCBpZiBhbiBhbGxpYW5jZSB3YXMgZm9ybWVkIGJldHdlZW4gNCBzdGF0ZXMgdGhlbiB0aGVyZSB3b3VsZCA2IG5ldyBhbGxpYW5jZXMgaW4gdGhlIGRhdGEgc2V0IGJlY2F1c2UgdGhlcmUgaXMgYW4gYWxsaWFuY2UgYmV0d2VlbiBlYWNoIG9mIHRoZSA0IG1lbWJlcnMuIFNpbWlsYXJseSwgaWYgYW4gYWxsaWFuY2UgYmV0d2VlbiA0IHN0YXRlcyB3ZXJlIHRlcm1pbmF0ZWQgdGhhdCB3b3VsZCBiZSA2IGxlc3MgYWxsaWFuY2VzLgoKCgpgYGB7ciBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9OH0KZGlyX2FsXzAgPC0gZmlsdGVyKGRpcl9hbCwgZGlyX2FsJGR5YWRfc3RfeWVhciAlaW4lIGMoMTkwMDoyMDEyKSkKYWxsX3N0IDwtIGdhdGhlcihkaXJfYWxfMCwgdHJlYXR5X3R5cGUsIGlkaWNhdG9yLCBkZWZlbnNlOmVudGVudGUpCmFsbF9zdCA8LSBhbGxfc3RbIWFsbF9zdCRpZGljYXRvciAlaW4lICAwLF0KYWxsX3N0JGR5YWRfZW5kX3llYXJbYWxsX3N0JGR5YWRfZW5kX3llYXIgJWluJSBOQV0gPSAyMDE2CmFsX3N0X2NvdW50IDwtIGFsbF9zdFssIGMoMyw1LDgsMTEsMTUpXQphbF9zdF9jb3VudCRjb3VudCA8LSAxIAoKZ3Bfc3QgPC0gYWdncmVnYXRlKGNiaW5kKGNvdW50KSB+IGR5YWRfc3RfeWVhcit0cmVhdHlfdHlwZSwgZGF0YSA9YWxfc3RfY291bnQsIEZVTiA9IHN1bSApCgphIDwtIGdncGxvdCgpICsKICB4bGFiKCJZZWFyIikgKwogIHlsYWIoIkNvdW50IikrCiAgZ2VvbV9iYXIoZGF0YSA9IGFsX3N0X2NvdW50LCBhZXMoeCA9IGR5YWRfc3RfeWVhcikpICsKICBnZ3RpdGxlKCJUb3RhbCBBbGxpYW5jZXMgYnkgWWVhciB0aGV5IHN0YXJ0ZWQiKSsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPTAsIHltYXg9bWF4KDQ1MCksIGZpbGw9Q29uZmxpY3QpLGFscGhhPTAuMikrCiAgZ2d0aXRsZSgiTnVtYmVyIG9mIEFsbGlhbmNlcyBGb3JtZWQiKSArCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IC41KSkgKyAKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXM9Yygic2FsbW9uIiwgInBhbGV0dXJxdW9pc2UzIiwgImxpZ2h0c3RlZWxibHVlMiIsICJsaWdodHN0ZWVsYmx1ZTQiLCAibGlnaHRzdGVlbGJsdWUzIiwgInBpbmszIikpICsgZmFjZXRfd3JhcCh+dHJlYXR5X3R5cGUsIG5yb3cgPSAxICkKCmI8LSBnZ3Bsb3QoKSArCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJDb3VudCIpKwogIGdlb21fYmFyKGRhdGEgPSBhbF9zdF9jb3VudFthbF9zdF9jb3VudCRkeWFkX2VuZF95ZWFyIDwgMjAxNiwgXSwgYWVzKHggPSBkeWFkX2VuZF95ZWFyKSkgKwogIGdndGl0bGUoIk51bWJlciBvZiBBbGxpYW5jZXMgVGVybWluYXRlZCIpKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49MCwgeW1heD1tYXgoNDUwKSwgZmlsbD1Db25mbGljdCksYWxwaGE9MC4yKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gLjUpKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkgKyBmYWNldF93cmFwKH50cmVhdHlfdHlwZSwgbnJvdyA9IDEpCgpncmlkLmFycmFuZ2UoYSxiLCBucm93ID0yKQoKCmBgYAoKTW9zdCBvZiB0aGUgYWxsaWFuY2VzIGZvcm1lZCB3ZXJlIGF0IHRoZSBlbmQgb2YgV1dJSSBhbmQgZHVyaW5nIHRoZSBDb2xkIFdhci4gQWxzbywgdGhlIG1vc3QgZnJlcXVlbnRseSBmb3JtZWQgYWxsaWFuY2VzIHdlcmUgZGVmZW5zZSBhbmQgZW50ZW50ZS4gU3VycHJpc2luZ2x5LCBpbiB5ZWFycyB0aGF0IHNlZSBhIGxhcmdlIGluY3JlYXNlIGluIHRoZSBudW1iZXIgb2YgYWxsaWFuY2VzIGZvcm1lZCB0aGVyZSBpcyBhbHNvIGFuIGluY3JlYXNlIGluIHRoZSBudW1iZXIgb2YgYWxsaWFuY2VzIHRoYXQgd2VyZSB0ZXJtaW5hdGVkLiBUbyBkaWcgaW4gZnVydGhlciB0byBnZXQgYSBiZXR0ZXIgdW5kZXJzdGFuZCBvZiB3aGF0IHR5cGVzIG9mIHRyZWF0aWVzIHdlcmUgZm9ybWVkIGFuZCB3aHkgdGhleSBlbmRlZCwgd2UgbG9va2VkIGF0IGluZGl2aWR1YWwgY291bnRyaWVzLiAKClRoZSBmb2xsb3dpbmcgY2hhcnRzIGFyZSBhbGwgb3JnYW5pemVkIHRoZSBzYW1lIHdheSwgdGhleSBzaG93IGEgdGltZWxpbmUgb2Ygd2hlbiB0aGUgYWxsaWFuY2VzIHN0YXJ0ZWQgdGlsbCBlaXRoZXIgdGhlIGVuZCBvZiB0aGUgYWxsaWFuY2UgKHNob3duIGluIHJlZCkgb3IgdGlsbCAyMDEyIGlmIHRoZSBhbGxpYW5jZSB3YXMgb2JzZXJ2ZWQgaW4gZWZmZWN0IGFzIG9mIERlY2VtYmVyIDMxLCAyMDEyIChzaG93biBpbiBibHVlKS4gVGhlIGNoYXJ0cyBhcmUgZmFjZXR0ZWQgdG8gc2hvdyB0aGUgZGlmZmVyZW50IHR5cGVzIG9mIGFsbGlhbmNlcyBiZWNhdXNlIG1hbnkgb2YgdGhlIGFsbGlhbmNlIHR5cGVzIG92ZXJsYXAuIEZvciBleGFtcGxlLCBvbmUgYWxsaWFuY2UgY291bGQgYmUgYm90aCBhIGRlZmVuc2UgYW5kIGVudGVudGUgYWxsaWFuY2UsIHNvIHRvIGdldCBhIGJldHRlciB2aXN1YWwgcmVwcmVzZW50YXRpb24gd2Ugc2VwYXJhdGVkIHRoZSB0eXBlcyBvZiBhbGxpYW5jZXMuIFdlIGZvY3VzZWQgdGhpcyBwYXJ0IG9mIHRoZSBhbmFseXNpcyBvbiB0aGUgVW5pdGVkIFN0YXRlcyBiZWNhdXNlIGl0IGlzIGEgbWFqb3IgcG93ZXIgYW5kIHRodXMgaXMgaW52b2x2ZWQgaW4gbWFueSBvZiB0aGUgbWlsaXRhcnkgYWxsaWFuY2VzIHRocm91Z2hvdXQgaGlzdG9yeS4gCgoKCioqVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhICoqIAoKYGBge3IgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTl9CmFsX3VzX3lyIDwtIGZpbHRlcihkaXJfYWxfeWVhciwgZGlyX2FsX3llYXIkc3RhdGVfbmFtZTEgJWluJSAiVW5pdGVkIFN0YXRlcyBvZiBBbWVyaWNhIikKYWxfdXNfeXIgPC0gZ2F0aGVyKGFsX3VzX3lyLCBUcmVhdHksIGlkaWNhdG9yLCBkZWZlbnNlOmVudGVudGUpICAgCmFsX3VzX3lyIDwtIGFsX3VzX3lyWyFhbF91c195ciRpZGljYXRvciAlaW4lICAwLF0KYWxfdXNfeXIkZHlhZF9lbmRfeWVhclthbF91c195ciRkeWFkX2VuZF95ZWFyICVpbiUgTkFdID0gMjAxNgphbF91c195ciA8LSBhbF91c195clssIGMoMSw1LDgsMTEsMTQsMTYpXQphbF91c195ciRjb3VudCA9IDEgCmFsX3VzX3lyJFN0YXR1cyA8LSAiIgphbF91c195ciRTdGF0dXNbYWxfdXNfeXIkZHlhZF9lbmRfeWVhciA8IDIwMTJdIDwtICJFbmRlZCIKYWxfdXNfeXIkU3RhdHVzW2FsX3VzX3lyJGR5YWRfZW5kX3llYXI9PSAyMDEyXSA8LSAiT25nb2luZyIKCmdncGxvdCgpICsgCiAgeGxhYigiWWVhciIpICsKICB5bGFiKCJDb3VudHJ5IikrCiAgZ2VvbV9wb2ludChkYXRhID1hbF91c195ciwgYWVzKHg9eWVhciwgeSA9IHN0YXRlX25hbWUyLCBjb2xvciA9U3RhdHVzKSwgYWxwaGEgPSAuNSkgKyAKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPSJBZmdoYW5pc3RhbiIsIHltYXg9IlppbWJhYndlIiwgZmlsbD1Db25mbGljdCksYWxwaGE9MC4xNSkgKyAKICBnZ3RpdGxlKCJVUyBBbGxpYW5jZXMgIikrCiAgdGhlbWVfY2xhc3NpYygpKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCJzYWxtb24iLCAicGFsZXR1cnF1b2lzZTMiLCAibGlnaHRzdGVlbGJsdWUyIiwgImxpZ2h0c3RlZWxibHVlNCIsICJsaWdodHN0ZWVsYmx1ZTMiLCAicGluazMiKSkgKyBmYWNldF93cmFwKH50cmVhdHlfdHlwZSwgbnJvdyA9IDEpKwogIGZhY2V0X3dyYXAoflRyZWF0eSwgbnJvdyA9IDEgKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJyaWdodCIsIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAuNSkpIAoKYGBgCgpMb29raW5nIGF0IHRoZSBhbGxpYW5jZXMgZm9yIHRoZSBVUywgd2Ugc2VlIHRoYXQgbW9zdCBkZWZlbnNlIGFsbGlhbmNlcyBhcmUgc3RpbGwgaW4gZWZmZWN0IHRvZGF5LiBUaGVyZSB3ZXJlIGhhbmRmdWwgb2YgYWxsaWFuY2VzIHdpdGggU291dGggQW1lcmljYW4gY291bnRyaWVzIHRoYXQgZW5kZWQgdG93YXJkcyB0aGUgZW5kIG9mIFdXSUkgYnV0IHRoZSBVUyBlbnRlcmVkIGEgZGlmZmVyZW50IGFsbGlhbmNlIHdpdGggdGhvc2Ugc2FtZSBjb3VudHJpZXMgaW1tZWRpYXRlbHkuIFRoZSB0cmVhdGllcyBpbiBlZmZlY3Qgd2l0aCB0aGUgU291dGggQW1lcmljYW4gY291bnRyaWVzIGlzIHRoZSBJbnRlci1BbWVyaWNhbiBUcmVhdHkgb2YgUmVjaXByb2NhbCBBc3Npc3RhbmNlIChSaW8gUGFjdCkgd2hlcmUgaWYgdGhlcmUgaXMgYW4gYXR0YWNrIGFnYWluc3Qgb25lIGNvdW50cnksIGl0IGlzIGNvbnNpZGVyZWQgYW4gYXR0YWNrIGFtb25nIGFsbCB0aGUgQW1lcmljYXMgY291bnRyaWVzIGluIHRoZSBhbGxpYW5jZS4gVGhpcyBhbGxpYW5jZSB3YXMgY3JlYXRlZCBuIDE5NDkgYW5kIGNvbnRpbnVlcyB0aWxsIHRvZGF5IChUaGUgUmlvIFBhY3QgYXQgYSBHbGFuY2UpLiAKCllvdSBjYW4gYWxzbyBzZWUgYSBzaW1pbGFyIHBhdHRlcm4gb2Ygb25nb2luZyBhbGxpYW5jZXMgZm9yIGRlZmVuc2UgZW50ZW50ZSBhbmQgbm9uYWdncmVzc2lvbiB0cmVhdHkgdHlwZXMuIE5BVE8sIGEgZGVmZW5zaXZlLCBlbnRlbnRlIGFuZCBub25hZ2dyZXNzaW9uIGFsbGlhbmNlLCB3YXMgZm9ybWVkIGluIDE5NDcgYW5kIGlzIHN0aWxsIGluIGVmZmVjdCB0aWxsIHRvZGF5LiBOQVRPIGludm9sdmVzIDI4IGNvdW50cmllcyBhbmQgYWNjb3VudHMgZm9yIHRoZSBoaWdoIG51bWJlciBvZiBhbGxpYW5jZXMgZm9ybWVkIGluIDE5NDkgZm9yIHRoZSAzIHR5cGVzIChGb3JtYXRpb24gb2YgTkFUTykuIAoKVGhlIGVudGVudGUgYWxsaWFuY2VzIGZvbGxvdyBhIHNpbWlsYXIgcGF0dGVybiB3aGVyZSB0aGUgYWxsaWFuY2UgZW5kZWQgYW5kIHdhcyBpbW1lZGlhdGVseSByZWZvcm1lZC4gVGhlcmUgd2VyZSBhIGZldyBjb3VudHJpZXMgd2hlcmUgdGhlcmUgd2FzIGFuIGVudGVudGUgYWxsaWFuY2UgZm9ybWVkIHRvd2FyZHMgdGhlIGVuZCBvZiB0aGUgS29yZWFuIFdhciBhbmQgZW5kZWQgYSBmZXcgeWVhcnMgYWZ0ZXIgdGhlIGVuZCBvZiB0aGUgVmlldG5hbSB3YXIuIFRoZSBtYWpvcml0eSBvZiB0aGUgY291bnRyaWVzIHRoYXQgZm9sbG93IHRoZSBkZXNjcmliZWQgcGF0dGVycyBhcmUgaW4gQXNpYSBvciBBdXN0cmFsaWEuIFRoaXMgaXMgcmVhc29uYWJsZSBjb25zaWRlcmluZyB0aGV5IHdlcmUgcGFydGljaXBhbnRzIGlzIHRoZSBWaWV0bmFtIFdhci4gQWxzbywgdGhlIGRlZmVuc2UgYW5kIGVudGVudGUgYWxsaWFuY2UgYmV0d2VlbiB0aGUgVVMgYW5kIEN1YmEgZW5kZWQgZHVyaW5nIHRoZSBWaWV0bmFtIFdhciwgaW5kaWNhdGVkIGluIHRoZSBncmFwaCBhYm92ZSwgd2hlbiBDdWJhIHdhcyBwcm92aWRpbmcgbWlsaXRhcnkgc3VwcG9ydCB0byB0aGUgVmlldG5hbWVzZS4gQWxzbywgZHVyaW5nIHRoZSBWaWV0bmFtIHdhciwgdGhlcmUgd2FzIGEgbmV1dHJhbGl0eSBhbGxpYW5jZSBmb3IgYSBmZXcgeWVhcnMgYmV0d2VlbiB0aGUgVVMgYW5kIGNvdW50cmllcyB0aGF0IHBhcnRpY2lwYXRlZCBpbiB0aGUgVmlldG5hbSB3YXIuIFRoaXMgYWxsaWFuY2Ugd2FzIGNhbGxlZCB0aGUgSW50ZXJuYXRpb25hbCBBZ3JlZW1lbnQgb24gdGhlIE5ldXRyYWxpdHkgb2YgTGFvcyBzdGFydGluZyBpbiAxOTYxIGFuZCB3YXMgdGVybWluYXRlZCB3aGVuIHdhcyBEZW1vY3JhdGljIFJlcHVibGljIG9mIFZpZXRuYW0gdmlvbGF0ZWQgdGhlIHRlcm1zIG9mIHRoZSB0cmVhdHkgMiB5ZWFycyBsYXRlciAoVmlldG5hbSBXYXIgSGlzdG9yeSkuICAKCgoqKkNvbmNsdXNpb25zICYgTmV4dCBTdGVwcyAqKgoKU2luY2Ugd2UgYXJlIG1haW5seSBmb2N1c2luZyBvbiBsYXJnZS1zY2FsZSB3YXJzIHRoYXQgaW52b2x2ZWQgdmFyaW91cyBjb3VudHJpZXMsIG1hbnkgdHJlYXRpZXMgd2VyZSBjcmVhdGVkIGFuZCBicm9rZW4uIEZvciBleGFtcGxlLCBXYXJzYXcgUGFjdCB3YXMgY3JlYXRlZCBhcyBhIGNvdW50ZXIgd2VpZ2h0IHRvIHRoZSBOQVRPIFBhY3QgY3JlYXRlZCBhdCBlbmQgb2YgV1dJSS4gVGhlIFVTLCBHcmVhdCBCcml0YWluIGFuZCB0aGVpciBhbGxpZXMgYmVjYW1lIHBhcnQgb2YgTkFUTyBhbmQgdGhlIFNvdmlldCBVbmlvbiBhbmQgaXRzIEFsbGllcyBiZWNhbWUgcGFydCBvZiB0aGUgV2Fyc2F3IHBhY3QuIE9uY2UgdGhlIFVTU1IgZGlzc29sdmVkIG1hbnkgb2YgdGhlIHNhdGVsbGl0ZSBuYXRpb25zLCB0aGUgV2Fyc2F3IFBhY3QgbWVtYmVycyBqb2luZWQgTkFUTy4gV2l0aCBOQVRPIGFuZCB0aGUgZm9ybWF0aW9uIG9mIHRoZSBVbml0ZWQgTmF0aW9ucywgaXQgaXMgaGFyZCB0byBzYXkgd2hpY2ggY291bnRyaWVzIHdpbGwgcGFydGljaXBhdGUgaW4gdGhlIG5leHQgd2FyLiBGb3IgZXhhbXBsZSwgYmVmb3JlIHRoZSBiZWdpbm5pbmcgb2YgdGhlIFdhciBvbiBBZmdoYW5pc3RhbiwgdGhlIHNlY3VyaXR5IGNvdW5jaWwgaGFkIHRvIGF1dGhvcml6ZSB0aGUgVW5pdGVkIFN0YXRlcyBhbmQgTkFUTyBhbGxpZXMgdG8gb3JnYW5pemUgYW4gb2ZmZW5zaXZlIGFnYWluc3QgYWwtUWFlZGEgKFdpdHRlKS4gVGhpcyB0eXBlIG9mIHJlZ3VsYXRpb24gbWFrZXMgaXQgaGFyZCB0byBkZXRlcm1pbmUgaG93IGZ1dHVyZSB3YXJzIHdpbGwgcGxheSBvdXQuIE9uZSB0aGluZyB0aGF0IHdhcyBpbnRlcmVzdGluZyBpcyB0aGF0IG9uY2UgYSB0cmVhdHkgZmFsbHMgYXBhcnQsIHRoZSBtZW1iZXJzIHRyeSB0byBqb2luIGFub3RoZXIgdHJlYXR5IHdoaWNoIGlzIHdoeSB3ZSBzZWUgc3Bpa2VzIGlzIHRoZSBtZWRpYW4gbnVtYmVyIG9mIGFsbGlhbmNlcyB0b3dhcmRzIHRoZSBlbmQgb2YgdGhlIHdhcnMuIAoKT25lIG9mIHRoZSB0aGluZ3MgdGhhdCB3YXMgaGFyZCB0byB3b3JrIHdpdGggdGhpcyBkYXRhIHNldCBpcyB0aGF0IGl0IHdhcyBpbXBvc3NpYmxlIHRvIHRlbGwgd2hpY2ggYWxsaWFuY2VzIHdlcmUgcGFydCBvZiBhIGxhcmdlciB0cmVhdHkuIEZvciBleGFtcGxlLCBpZiB0aGVyZSB3YXMgYSBkYXRhIHBvaW50IGZvciBhbiBhbGxpYW5jZSBiZXR3ZWVuIHRoZSBVUyBhbmQgdGhlIFVLIGluIDE5NjcsIHRoZXJlIHdhcyBubyBpbmRpY2F0aW9uIG9mIGlmIGl0IHdhcyBOQVRPIG9yIHNvbWUgb3RoZXIgdHJlYXR5LiAgVGhpcyBhbHNvIG1hZGUgaXQgaGFyZCB0byB0ZWxsIHdoZW4gYSBjb3VudHJ5IGpvaW5lZCBhbiBleGlzdGluZyBhbGxpYW5jZS4gRm9yIGV4YW1wbGUsIHdoZW4gR2VybWFueSBqb2luZWQgTkFUTyB0aGVyZSB3ZXJlIGRhdGEgcG9pbnRzIGZvciBhbiBhbGxpYW5jZSBiZXR3ZWVuIEdlcm1hbnkgYW5kIHRoZSBOQVRPIG1lbWJlcnMgYnV0IGl0IGlzIG5vdCBlYXN5IHRvIGRpc2Nlcm4gdGhhdCBHZXJtYW55IGpvaW4gTkFUTyB3aXRob3V0IHNvbWUgaW50ZXJuZXQgcmVzZWFyY2guIAoKVGhlIG90aGVyIGRvd25mYWxsIG9mIHRoaXMgZGF0YSBzZXQgaXMgdGhhdCBpdCBvbmx5IGNvbnNpZGVycyBmb3JtYWwgbWlsaXRhcnkgYWxsaWFuY2VzLiBJdCBkb2VzIG5vdCBjb25zaWRlciBvdGhlciB0eXBlcyBvZiBhbGxpYW5jZXMgc3VjaCBhcyB0aGUgVW5pdGVkIE5hdGlvbnMgJiBzZWN1cml0eSBjb3VuY2lsIG9yIGEgdHJhZGUgYWdyZWVtZW50LiBGb3IgZXhhbXBsZSwgSmFwYW4gaXMgbm90IGluIGFueSBtaWxpdGFyeSBhbGxpYW5jZSBjdXJyZW50bHkgYnV0IGl0IGRvZXMgaGF2ZSB2ZXJ5IGNsb3NlIHRpZXMgdG8gdGhlIFVuaXRlZCBTdGF0ZXMgdG9kYXksIGFuZCB0aGlzIGluZm9ybWF0aW9uIGlzIG5vdCBjYXB0dXJlZCBpbiB0aGUgZGF0YSBzZXQuIAoKIyMjIyBNaWxpdGFyaXplZCBJbnRlcnN0YXRlIERpc3B1dGVzCiAgClRoZSBkYXRhIGlzIHJpY2ggYW5kIGNvbnRhaW5zIG1hbnkgZGltZW5zaW9ucyBzdWNoIGFzIHRoZSBvdXRjb21lcywgc2V0dGxlbWVudHMsIHRoZSBudW1iZXIgb2YgZmF0YWxpdGllcywgbWluaW11bSBkdXJhdGlvbiwgdGhlIGhpZ2hlc3QgYWN0aW9uIHRha2VuIGFuZCBob3N0aWxpdHkgbGV2ZWwgZHVyaW5nIGVhY2ggbWlsaXRhcml6ZWQgY29uZmxpY3QgaW4gdGhlIGxhc3QgY2VudHVyeS4gSGVuY2UgYXMgdGhlIGZpcnN0IHN0ZXAsIHdlIHNlbGVjdGVkIGEgZmV3IHZhcmlhYmxlcyBhbmQgcGxvdHRlZCB0aGVtIGluIGEgcGNwIHRvIHRyeSBhbmQgc3BvdCBjb3JyZWxhdGlvbnMuCiAgCmBgYHtyIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKbGlicmFyeShHR2FsbHkpCgojcGF0aCA9ICIvaG9tZS92YWd1aWFyL2NvbF9ody92aXNfaHcvZmluYWwvZGF0YS8iCk1JREEgPSByZWFkLmNzdihmaWxlPSIuL2RhdGEvTUlEL01JREFfNC4wMS5jc3YiLCBzZXA9ICIsIikKCndhcl95ZWFyIDwtIGZ1bmN0aW9uKHgpewogIGlmKHggPj0gMTkxNCAmIHggPD0gMTkxOCkKICAgcmV0dXJuKCdXV0knKQogIGlmKHggPj0gMTkzOSAmIHggPD0gMTk0NSkKICAgcmV0dXJuKCdXV0lJJykKICBpZih4ID49IDE5NTAgJiB4IDw9IDE5NTMpCiAgIHJldHVybignS29yZWFuIFdhcicpCiAgaWYoeCA+PSAxOTU1ICYgeCA8PSAxOTc1KQogICByZXR1cm4oJ1ZpZXRuYW0gV2FyJykKICBpZih4ID49IDE5NDcgJiB4IDw9IDE5OTEpCiAgIHJldHVybignQ29sZCBXYXInKQogIGlmKHggPj0gMjAwMSAmIHggPD0gMjAxMCkKICAgcmV0dXJuKCdXYXIgaW4gQWZnaGFuaXN0YW4nKQogIGVsc2UKICAgIHJldHVybignTm8gV2FyJykKfQoKTUlEQSR3YXJ0aW1lIDwtIHNhcHBseShNSURBJFN0WWVhciwgd2FyX3llYXIpCgojI1BDUCBQTG90IAphbHBoYWJlbmRpbmcgPSAwLjUKd2FyIDwtIGdncGFyY29vcmQoTUlEQVtNSURBJFN0WWVhcj4xOTAwICYgTUlEQSR3YXJ0aW1lIT0nTm8gV2FyJyxdLCBjb2x1bW5zID0gYyg5OjExLCAxNDoxNiksIAogICAgICAgICAgICAgICAgICBzY2FsZSA9ICJ1bmltaW5tYXgiLCAKICAgICAgICAgICAgICAgICAgYWxwaGFMaW5lcyA9IGFscGhhYmVuZGluZywKICAgICAgICAgICAgICAgICAgZ3JvdXBDb2x1bW4gPSAid2FydGltZSIsIAogICAgICAgICAgICAgICAgICB0aXRsZT0iQ29ycmVsYXRpb25zIEluIFdhciBUaW1lIENvbmZsaWN0cyIpICsKICAgICAgICAgICAgICAgICAgdGhlbWVfY2xhc3NpYygpICsKICAgICAgICAgICAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCiAgICAgICAgICAgICAgICAgICNndWlkZXMoZmlsbD1ndWlkZV9sZWdlbmQodGl0bGU9IldhciBQZXJpb2QiLCAKICAgICAgICAgICAgICAgICAgICMgICAgICB0aXRsZS5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgICAgICAgICAgICAgICMgICAgIG5yb3c9MSkpIApwZWFjZSA8LSBnZ3BhcmNvb3JkKE1JREFbTUlEQSRTdFllYXI+MTkwMCAmIE1JREEkd2FydGltZT09J05vIFdhcicsXSwgY29sdW1ucyA9IGMoOToxMSwgMTQ6MTYpLCAKICAgICAgICAgICAgICAgICAgc2NhbGUgPSAidW5pbWlubWF4IiwKICAgICAgICAgICAgICAgICAgYWxwaGFMaW5lcyA9IGFscGhhYmVuZGluZywKICAgICAgICAgICAgICAgICAgZ3JvdXBDb2x1bW4gPSAid2FydGltZSIsIAogICAgICAgICAgICAgICAgICB0aXRsZT0iQ29ycmVsYXRpb25zIEluIFBlYWNlIFRpbWUgQ29uZmxpY3RzIikgKwogICAgICAgICAgICAgICAgICB0aGVtZV9jbGFzc2ljKCkgKwogICAgICAgICAgICAgICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKICAgICAgICAgICAgICAgICAgI2d1aWRlcyhmaWxsPWd1aWRlX2xlZ2VuZCh0aXRsZT0iV2FyIFBlcmlvZCIsIAogICAgICAgICAgICAgICAgICAgIyAgICAgIHRpdGxlLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICAgICAgICAgICAgIyAgICAgbnJvdz0xKSkgCmdyaWQuYXJyYW5nZSh3YXIsIHBlYWNlLCBucm93ID0gMikgIApgYGAKSW4gdGhlIGdyYXBoIHBsb3R0aW5nIFdhciBUaW1lIENvcnJlbGF0aW9ucywgd2Ugc2VlIHRoYXQgbW9zdCBvZiB0aGUgZGF0YSBwb2ludHMgZm9yIEZhdGFsaXR5LCBTZXR0bGVtZW50IGFuZCBPdXRjb21lIGdyYXZpdGF0ZSB0b3dhcmRzIHRoZSB0b3AgaGFsZi4gVGhlcmUncyBhbHNvIGEgaGlnaCBsZXZlbCBvZiBjb3JyZWxhdGlvbiBiZXR3ZWVuIHRob3NlIHRocmVlLiBNaW5pbXVtIER1cmF0aW9uIHdhcyBwYXJ0bHkgc2tld2VkIGFuZCB0aGUgcmVzdCB3ZXJlIGV2ZW5seSBkaXN0cmlidXRlZC4gQXMgZm9yIHRoZSBQZWFjZSBUaW1lIENvcnJlbGF0aW9ucywgdGhlIGZpcnN0IHRocmVlIHZhcmlhYmxlcyBzZWVtIHByZXR0eSBldmVubHkgZGlzdHJpYnV0ZWQgdG9vLgoKQmVsb3csIHdlIGRpZyBhIGxpdHRsZSBkZWVwZXIgaW50byB2YXJpYWJsZXMgbGlrZSBGYXRhbGl0aWVzLCBTZXR0bGVtZW50cyBhbmQgT3V0Y29tZXMgb2YgdGhlIGNvbmZsaWN0cy4gRWFjaCBncmFwaCBpcyBvdmVybGFpZCB3aXRoIHRoZSB0aW1lIHBlcmlvZCBvZiB0aGUgbWFqb3Igd2Fycy4gVGhyb3VnaCB0aGlzIGV4cGxvcmF0aW9uLCB3ZSB0cnkgdG8gc3BvdCBwb3NzaWJsZSBwcmVkaWN0b3JzIG9mIGEgd2FyLiAgCiAgCioqRmF0YWxhdGllcyBJbiBEaXNwdXRlcyBMZWFkaW5nIHRvIFdhcioqICAKCmBgYHtyIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KCiMgT3ZlcmxheSB3LyByZWN0YW5nbGUgdGhlbWUKeTJfaGlnaCA9OQpkID0gZGF0YS5mcmFtZSh4MT1jKDE5MTQsMTkzOSwgMTk0NywgMTk1MCwgMTk1NSwgMjAwMSksIHgyPWMoMTkxOCwgMTk0NSwgMTk5MSwgMTk1MywgMTk3NSwgMjAxMCksIHkxPWMoMCwwLDAsMCwwLDApLCB5Mj1jKHkyX2hpZ2gseTJfaGlnaCx5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCx5Ml9oaWdoKSwgQ29uZmxpY3Q9YygiV1dJIiwgIldXSUkiLCAiQ29sZCBXYXIiLCAiS29yZWFuIFdhciIsICJWaWV0bmFtIFdhciIsICJBZmdoYW5pc3RhbiBXYXIiKSwgcj1jKDEsMiwzLDQsNSw2KSkKCiNBZGRpbmcgTGFiZWxzIGZvciBGYWNldCB0aXRsZXMKZmFjZXRfbmFtZXMgPC0gYXNfbGFiZWxsZXIoYygKICAnMCcgPSAiTm9uZSIsCiAgJzEnID0gIjEtMjUgZGVhdGhzIiwKICAnMicgPSAiMjYtMTAwIGRlYXRocyIsCiAgJzMnID0gIjEwMS0yNTAgZGVhdGhzIiwKICAnNCcgPSAiMjUxLTUwMCBkZWF0aHMiLAogICc1JyA9ICI1MDEtOTk5IGRlYXRocyIsCiAgJzYnID0gIk1vcmUgdGhhbiA5OTkgZGVhdGhzIiwKICAnLTknID0gIk1pc3NpbmcgRGF0YSIKKSkKCmdncGxvdCgpICsgCiAgZ2VvbV9iYXIoZGF0YT1NSURBW01JREEkRW5kWWVhcj4xOTAwICYgTUlEQSRGYXRhbGl0eSE9MCAmIE1JREEkRmF0YWxpdHkhPS05LF0sIGFlcyh4ID0gRW5kWWVhciksICAgc3RhdD0iY291bnQiKSArCiAgZmFjZXRfd3JhcCh+RmF0YWxpdHksIG5yb3c9IDgsIGxhYmVsbGVyPWZhY2V0X25hbWVzKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlQYWwpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPXkxLCB5bWF4PXkyLCBmaWxsPUNvbmZsaWN0KSwgYWxwaGE9MC4xNSkgKwogIGdndGl0bGUoIk51bWJlciBPZiBEaXNwdXRlcyBXaXRoIEZhdGFsaXRpZXMgQnkgWWVhciIpICsKICB4bGFiKCJFbmQgWWVhciIpICsKICB5bGFiKCJDb3VudCIpCgpgYGAKSW4gdGhlIGdyYXBoIGFib3ZlIHdlIGhhdmUgcGxvdHRlZCB0aGUgRmF0YWxpdGllcyBvY2N1cnJpbmcgZHVlIHRvIG1pbGl0YXJpemVkIGNvbmZsaWN0cyBldmVyeSB5ZWFyIHNpbmNlIHRoZSB5ZWFyIDE5MDAuIFdlJ3ZlIGZhY2V0ZWQgdGhlIGdyYXBocyBieSB0aGUgbnVtYmVyIG9mIGZhdGFsaXRpZXMgc3RhcnRpbmcgZnJvbSAxLTI1LCAyNS0xMDAsIDEwMS0yNTAgYW5kIHNvIG9uLiBXaXRoaW4gZWFjaCBmYWNldCwgdGhlIGRhdGEgaXMgbWlsZGx5IGludGVyc3BlcnNlZCB3aXRoIGEgbGFyZ2VyIGNvbmNlbnRyYXRpb24gZHVyaW5nIHRoZSB3YXIgeWVhcnMgYW5kIHNwYXJzZSBkaXN0cmlidXRpb24gYXQgb3RoZXIgdGltZXMuIEJ1dCwgaW50ZXJlc3RpbmdseSBzbywgdGhlcmUgd2VyZSBjb25mbGljdHMgcmVzdWx0aW5nIGluIG1vcmUgdGhhbiA5OTkgZGVhdGhzIGluIHRoZSB5ZWFycyBsZWFkaW5nIHRvIHRoZSBlYWNoIGFuZCBldmVyeSBtYWpvciB3YXIuIEFuZCBpbiBmb3VyIG9mIHRob3NlIHllYXJzLCBuYW1lbHkgMTkxMywgMTkzOCwgMTk1NSwgYW5kIDIwMDEsIHdlIHNlZSBzcGlrZXMgaW4gdGhlIG51bWJlciBvZiBkZWF0aHMuIFRoaXMgY291bGQgYmUgaW5kaWNhdGl2ZSBvZiB0aGUgZmFjdCB0aGF0IHRob3NlIGNvbmZsaWN0cyBmb3JjZWQgYW4gaW50ZXJuYXRpb25hbCBpbnZvbHZlbWVudCBpbiB0aGUgd2Fycy4KCioqU2V0dGxlbWVudCBvZiBEaXNwdXRlcyBMZWFkaW5nIHRvIFdhcioqICAKYGBge3IgZmlnLndpZHRoPTE1LCBmaWcuaGVpZ2h0PTZ9CgojIE92ZXJsYXkgdy8gcmVjdGFuZ2xlIHRoZW1lCnkyX2hpZ2ggPSA5CmQgPSBkYXRhLmZyYW1lKHgxPWMoMTkxNCwxOTM5LCAxOTQ3LCAxOTUwLCAxOTU1LCAyMDAxKSwgeDI9YygxOTE4LCAxOTQ1LCAxOTkxLCAxOTUzLCAxOTc1LCAyMDEwKSwgeTE9YygwLDAsMCwwLDAsMCksIHkyPWMoeTJfaGlnaCx5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCx5Ml9oaWdoLHkyX2hpZ2gpLCBDb25mbGljdD1jKCJXV0kiLCAiV1dJSSIsICJDb2xkIFdhciIsICJLb3JlYW4gV2FyIiwgIlZpZXRuYW0gV2FyIiwgIkFmZ2hhbmlzdGFuIFdhciIpLCByPWMoMSwyLDMsNCw1LDYpKQoKCiNBZGRpbmcgTGFiZWxzIGZvciBGYWNldCB0aXRsZXMKZmFjZXRfbmFtZXMgPC0gYXNfbGFiZWxsZXIoYygKICAnMScgPSAiTmVnb3RpYXRlZCIsCiAgJzInID0gIkltcG9zZWQiLAogICczJyA9ICJOb25lIiwKICAnNCcgPSAiVW5jbGVhciIsCiAgJy05JyA9ICJNaXNzaW5nIERhdGEiCikpCgpnZ3Bsb3QoKSArIAogIGdlb21fYmFyKGRhdGE9TUlEQVtNSURBJEVuZFllYXI+MTkwMCAmIE1JREEkU2V0dGxlIT0zICYgTUlEQSRTZXR0bGUhPSctOScsIF0sIGFlcyh4ID0gRW5kWWVhciksIHN0YXQ9ImNvdW50IikgKwogIGZhY2V0X3dyYXAoflNldHRsZSwgbnJvdz0gNSwgbGFiZWxsZXI9ZmFjZXRfbmFtZXMpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBteVBhbCkgKwogIGdlb21fcmVjdChkYXRhPWQsIG1hcHBpbmc9YWVzKHhtaW49eDEsIHhtYXg9eDIsIHltaW49eTEsIHltYXg9eTIsIGZpbGw9Q29uZmxpY3QpLCBhbHBoYT0wLjE1KSArCiAgZ2d0aXRsZSgiTnVtYmVyIE9mIERpc3B1dGVzIFdpdGggU2V0dGxlbWVudCBPdXRjb21lcyBCeSBZZWFyIikgKwogIHhsYWIoIkVuZCBZZWFyIikgKwogIHlsYWIoIkNvdW50IikKYGBgCkluIHRoZSBncmFwaCBhYm92ZSB3ZSBoYXZlIHBsb3R0ZWQgdGhlIFNldHRsZW1lbnQgb3V0Y29tZXMgb2YgZGlmZmVyZW50IG1pbGl0YXJpemVkIGNvbmZsaWN0cyBldmVyeSB5ZWFyIHNpbmNlIHRoZSB5ZWFyIDE5MDAuIFdlJ3ZlIGZhY2V0ZWQgdGhlIGdyYXBocyBieSB0aGUgU2V0dGxlbWVudCB0eXBlcyBhbmQgZm9yIHNpbXBsaWNpdHkgd2UndmUgbGVmdCBvdXQgbWlzc2luZyBkYXRhIG9yIHNldHRsZW1lbnRzIHRoYXQgd2VyZSB1bmNsZWFyLiAgCiAgClN1cnByaXNpbmdseSwgd2UgZG9uJ3Qgc2VlIGFueSBjb3JyZWxhdGlvbnMgYmV0d2VlbiBJbXBvc2VkL05lZ290aWF0ZWQgU2V0dGxlbWVudHMgYW5kIHRoZSB3YXIuIEJ1dCBvbiBzZWNvbmQgdGhvdWdodCwgdGhlIG51bWJlciBvZiBTZXR0bGVtZW50cywgd291bGQgbm90IGJlIGFuIGltcG9ydGFudCBwcmVkaWN0b3Igb2Ygd2FyLiBUaGlzIGNvdWxkIGJlIGR1ZSB0byB0aGUgZmFjdCB0aGF0IHNvbWUgU2V0dGxlbWVudHMsIHN1Y2ggYXMgc3VjaCBhcyB0aGUgVHJlYXR5IG9mIFZlcnNhaWxsZXMgW1RyZWF0eSBvZiBWZXJzYWlsbGVzXSB3aGljaCB3YXMgcHVuaXRpdmUgYW5kIGNvbXBsZXggaW4gbmF0dXJlLCBoYWQgYSBtYWpvciByb2xlIGluIHNoYXBpbmcgdGhlIHBvbGl0aWNhbCBjbGltYXRlIG9mIE5hemkgR2VybWFueS4gQnV0IHNpbmNlIHRoZSBkYXRhIGRvZXNuJ3QgZGVsdmUgaW50byB0aGUgcXVhbGl0YXRpdmUgYXNwZWN0cyBvZiB0aGVzZSBTZXR0bGVtZW50cyBhbmQgaXQgaXMgb2YgbGl0dGxlIG9yIG5vIHNpZ25pZmljYW5jZSB0byBvdXIgZXhwbG9yYXRpb24uICAKICAKKipPdXRjb21lcyBvZiBEaXNwdXRlcyBMZWFkaW5nIHRvIFdhcioqICAKCmBgYHtyIGZpZy53aWR0aD0xNSwgZmlnLmhlaWdodD0xMH0KCiMgT3ZlcmxheSB3LyByZWN0YW5nbGUgdGhlbWUKeTJfaGlnaCA9NjUKZCA9IGRhdGEuZnJhbWUoeDE9YygxOTE0LDE5MzksIDE5NDcsIDE5NTAsIDE5NTUsIDIwMDEpLCB4Mj1jKDE5MTgsIDE5NDUsIDE5OTEsIDE5NTMsIDE5NzUsIDIwMTApLCB5MT1jKDAsMCwwLDAsMCwwKSwgeTI9Yyh5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCx5Ml9oaWdoLHkyX2hpZ2gseTJfaGlnaCksIENvbmZsaWN0PWMoIldXSSIsICJXV0lJIiwgIkNvbGQgV2FyIiwgIktvcmVhbiBXYXIiLCAiVmlldG5hbSBXYXIiLCAiQWZnaGFuaXN0YW4gV2FyIiksIHI9YygxLDIsMyw0LDUsNikpCgpNSURBX28gPC0gZmlsdGVyKE1JREEsIE1JREEkT3V0Y29tZSAlaW4lIGMoMSwyLDMsNCw1LDYsOCwtOSkpCndhcl9vdXRjb21lIDwtIGZ1bmN0aW9uKHgpewogIGlmKHggPT0yKQogICByZXR1cm4oMSkKICBpZih4ID09IDQpCiAgIHJldHVybigzKQogIGVsc2UKICAgIHJldHVybih4KQp9CgpNSURBX28kV2FyT3V0Y29tZSA8LSBzYXBwbHkoTUlEQV9vJE91dGNvbWUsIHdhcl9vdXRjb21lKQoKCiNBZGRpbmcgTGFiZWxzIGZvciBGYWNldCB0aXRsZXMKZmFjZXRfbmFtZXMgPC0gYXNfbGFiZWxsZXIoYygKICAnMScgPSAiVmljdG9yeSBGb3IgRWl0aGVyIFNpZGUiLAogICczJyA9ICJZaWVsZCBCeSBFaXRoZXIgU2lkZSIsCiAgJzUnID0gIlN0YWxlbWF0ZSIsCiAgJzYnID0gIkNvbXByb21pc2UiLCAKICAnOCcgPSAiVW5jbGVhciIsCiAgJy05JyA9ICJNaXNzaW5nIERhdGEiCikpCgpnZ3Bsb3QoKSArIAogIGdlb21fYmFyKGRhdGE9TUlEQV9vW01JREFfbyRFbmRZZWFyPjE5MDAgJiBNSURBX28kV2FyT3V0Y29tZSE9Jy05JyAsIF0sIAogIGFlcyh4ID0gRW5kWWVhciksIHN0YXQ9ImNvdW50IikgKwogIGZhY2V0X3dyYXAofldhck91dGNvbWUsIG5yb3c9IDUsIGxhYmVsbGVyPWZhY2V0X25hbWVzKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gbXlQYWwpICsKICBnZW9tX3JlY3QoZGF0YT1kLCBtYXBwaW5nPWFlcyh4bWluPXgxLCB4bWF4PXgyLCB5bWluPXkxLCB5bWF4PXkyLCBmaWxsPUNvbmZsaWN0KSwgYWxwaGE9MC4xNSkgKwogIGdndGl0bGUoIk51bWJlciBPZiBEaXNwdXRlcyBXaXRoIE91dGNvbWVzIEJ5IFllYXIiKSArCiAgeGxhYigiRW5kIFllYXIiKSArCiAgeWxhYigiQ291bnQiKQpgYGAKCkluIHRoZSBncmFwaCBhYm92ZSB3ZSBoYXZlIHBsb3R0ZWQgdGhlIE91dGNvbWVzIG9mIGRpZmZlcmVudCBtaWxpdGFyaXplZCBjb25mbGljdHMgZXZlcnkgeWVhciBzaW5jZSB0aGUgeWVhciAxOTAwLiBXZSd2ZSBmYWNldGVkIHRoZSBncmFwaHMgYnkgdGhlIE91dGNvbWVzIGFuZCBmb3Igc2ltcGxpY2l0eSwgd2UndmUgbGVmdCBvdXQgbWlzc2luZyBkYXRhIG9yIG91dGNvbWVzIHRoYXQgd2VyZSB1bmNsZWFyLiBUaGVyZSBpcyBsaXR0bGUgZXZpZGVuY2UgdG8gc2hvdyB0aGF0IGNlcnRhaW4gdHlwZXMgT3V0Y29tZXMgd2VyZSBwcmVkaWN0aXZlIG9mIGEgd2FyLiBCdXQgc3VycHJpc2luZ2x5IHNvLCB3ZSBzZWUgdGhhdCBTdGFsZW1hdGVzIHBlYWtlZCBkdXJpbmcgdGhlIG1pZGRsZSBvZiBhbiBvbmdvaW5nIHdhci4gV2Ugc2VlIHRoYXQgaW4gV1dJSSwgdGhlIFZpZXRuYW0gV2FyIGFuZCBkdXJpbmcgV2FyIGluIEFmZ2hhbmlzdGFuLiBPbiBmdXJ0aGVyIGFuYWx5c2lzLCB0aGUgeWVhcnMgdGhhdCBjb3JyZXNwb25kIHRvIHRoZSBzcGlrZSBpbiBzdGFsZW1hdGVzIGluIFdXMiBhbmQgdGhlIFZpZXRuYW0gV2FyIHdlcmUgdGhlIGV4YWN0IHllYXJzIGluIHdoaWNoIHRoZSBVUyBlbnRlcmVkIGJvdGggdGhvc2Ugd2FyczsgbmFtZWx5IDE5NDIgW1RoZSBVbml0ZWQgU3RhdGVzIERlY2xhcmVzIFdhciBvbiBKYXBhbl0gYW5kIDE5NjQgW0d1bGYgb2YgVG9ua2luIFJlc29sdXRpb25dLiBUaGUgaW50cm9kdWN0aW9uIG9mIGEgbWFqb3IgbWlsaXRhcnkgcG93ZXIgY291bGQgZXhwbGFpbiB0aGUgc2hpZnQgaW4gdGhlIHBvd2VyLgoKKipDb25jbHVzaW9ucyAmIE5leHQgU3RlcHMgKiogIApUaGUgZmFjZSBvZiBtb2Rlcm4gd2FyZmFyZSBoYXMgY2hhbmdlZCBkcmFtYXRpY2FsbHkgaW4gdGhlIHBhc3QgZmV3IGRlY2FkZXMuIFdpdGggdGVjaG5vbG9naWNhbCBhZHZhbmNlbWVudHMsIG1pbGl0YXJpZXMgbm93IHJlc29ydCB0byBlbGl0ZSBlbGVjdHJvbmljIHdhcmZhcmUgd2hpY2ggZW5hYmxlcyB0aGVtIHRvIHRhcmdldCB0aGVpciBlbmVtaWVzIHdpdGhvdXQgYW55IGh1bWFuIHByZXNlbmNlIG9uIHNpdGUuIEN5YmVyIHdhciBpcyBhbHNvIHdpZGVseSBlbXBsb3llZCB0byBjb25kdWN0IGVzcGlvbmFnZSBvciB0byBpbmZsdWVuY2UgYmlhc2VzIGluIHRoZSB3b3JsZC4gQ291bnRyaWVzIG1haW50YWluIGh1Z2UgYXJzZW5hbHMgb2Ygc3RyYXRlZ2ljIGRlZmVuc2Ugd2VhcG9ucyBzdWNoIGFzIEludGVyY29udGluZW50YWwgQmFsbGlzdGljIE1pc3NpbGVzIFtJQ0JNXSBhbmQgQmFsbGlzdGljIE1pc3NpbGUgTnVjbGVhciBTdWJtYXJpbmVzIFtTU0JOXSB0byBzZXJ2ZSBhcyBpbXBvcnRhbnQgZGV0ZXJyZW50cyB0byBpbnRlcm5hdGlvbmFsIGNvbmZsaWN0cy4gQW5kIGxlYXJuaW5nIGZyb20gdGhlIHBhc3QgcmF2YWdlcyBvZiB3YXIsIG1hbnkgY291bnRyaWVzIHN0YW5kIHVuaXRlZCBpbiBjb2xsZWN0aXZlbHkgcHVuaXNoaW5nIHJvZ3VlIG5hdGlvbnMgdGhyb3VnaCB0cmFkZSBlbWJhcmdvZXMgb3IgZWNvbm9taWMgbWFuZXV2ZXJzLiBXaXRoIHN1Y2ggYSBzaGlmdCBpbiBtaWxpdGFyeSBzdHJhdGVneSwgdGhlIE1JRCBkYXRhIG1heSBjb250YWluIG5ld2VyIGRpbWVuc2lvbnMgaW4gdGhlIGZ1dHVyZS4gVGhlIGludm9sdmVtZW50IG9mIGNlcnRhaW4gYWN0b3JzIG1heSBiZSBoYXJkZXIgdG8gcHJvdmUgb3IgcGluIHBvaW50IGFuZCB0aGUgZXhpc3RpbmcgdmFyaWFibGVzIG1heSBub3Qgc2VydmUgYXMgdmFsaWQgcHJlZGljdG9ycyBvZiBhbiBpbW1pbmVudCB3YXIuIAoKQnV0IGZvciB0aGUgbmV4dCBzdGVwcyBvZiB0aGlzIGV4cGxvcmF0aW9uLCB3ZSBjb3VsZCB3b3JrIHRvIGNvbnNpZGVyIHRoZSBpbnRlcnBsYXkgb2YgdHJhZGUgYW5kIGVjb25vbWljIHJlbGlhbmNlIG9uIHRoZSBwZWFjZSBiZXR3ZWVuIGJvcmRlcnMuIFRocm91Z2ggdGhlIE1JREIgZGF0YSBzZXQgd2UgY291bGQgZHJpbGwgZG93biBpbnRvIHRoZSBpbmRpdmlkdWFsIGRpc3B1dGVzIGJldHdlZW4gY291bnRyaWVzIGFuZCB0aGVpciBvY2N1cnJlbmNlcyBvdmVyIHRpbWUuIFN1cGVyaW1wb3NlIHRoYXQgb3ZlciBlY29ub21pYyBvciB0cmFkaW5nIHRpZXMgZHVyaW5nIHRoZSBzYW1lIHRpbWUgcGVyaW9kcywgb3IgdGhlIGZvcm1pbmcgb2Ygb3RoZXIgaW50ZXJuYXRpb25hbCBhbGxpYW5jZXMgYW5kIHdlIGNvdWxkIGhhdmUgdmFsdWFibGUgZmluZGluZ3MuCiAgCiAgCiMjIFNvdXJjZXMgCgoiQWJvdXQgdGhlIENvcnJlbGF0ZXMgb2YgV2FyIFByb2plY3QuIiBDb3JyZWxhdGVzIG9mIFdhci4gTi5wLiwgMDUgQXByLiAyMDE0LiBXZWIuIDE5IEFwci4gMjAxNy4gIAogIAoiQmF0dGxlZmllbGQ6IFZpZXRuYW0uIiBQQlMuIFB1YmxpYyBCcm9hZGNhc3RpbmcgU2VydmljZSwgbi5kLiBXZWIuIDE5IEFwci4gMjAxNy4gIAogIAoiQ29sZCBXYXIuIiBFbmN5Y2xvcMOmZGlhIEJyaXRhbm5pY2EuIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYSwgSW5jLiwgbi5kLiBXZWIuIDE5IEFwci4gMjAxNy4gIAogIApGb3JtYWwgQWxsaWFuY2VzICh2NC4xKS4gR2libGVyLCBEb3VnbGFzIE0uIDIwMDkuIEludGVybmF0aW9uYWwgbWlsaXRhcnkgYWxsaWFuY2VzLCAxNjQ4LTIwMDguIENRIFByZXNzLiAgICAgCiAgIAoiRm9ybWF0aW9uIG9mIE5BVE8uIiBIaXN0b3J5LmNvbS4gQSZFIFRlbGV2aXNpb24gTmV0d29ya3MsIDIwMTAuIFdlYi4gMTkgQXByLiAyMDE3LiAgCgoiR3VsZiBvZiBUb25raW4gUmVzb2x1dGlvbi4iIFdpa2lwZWRpYS4gV2lraW1lZGlhIEZvdW5kYXRpb24sIDE4IEFwci4gMjAxNy4gV2ViLiAxOSBBcHIuIDIwMTcuCgoiSUNCTSAtIEludGVyY29udGluZW50YWwgQmFsbGlzdGljIE1pc3NpbGUuIiBXaWtpcGVkaWEuIFdpa2ltZWRpYSBGb3VuZGF0aW9uLCAxOSBBcHIuIDIwMTcuIFdlYi4gMjAgQXByLiAyMDE3LgoKSm9uZXMsIERhbmllbCBNLiwgU3R1YXJ0IEEuIEJyZW1lciBhbmQgSi4gRGF2aWQgU2luZ2VyLiAxOTk2IC4iTWlsaXRhcml6ZWQgSW50ZXJzdGF0ZSBEaXNwdXRlcywgMTgxNi0xOTkyOiBSYXRpb25hbGUsIENvZGluZyBSdWxlcywgYW5kIEVtcGlyaWNhbCBQYXR0ZXJucy4iIENvbmZsaWN0IE1hbmFnZW1lbnQgYW5kIFBlYWNlIFNjaWVuY2UgMTU6MTYzLTIxMy4KCk5hdGlvbmFsIE1hdGVyaWFsIENhcGFiaWxpdGllcyAodjUuMCkuIFNpbmdlciwgSi4gRGF2aWQsIFN0dWFydCBCcmVtZXIsIGFuZCBKb2huIFN0dWNrZXkuICgxOTcyKS4gIkNhcGFiaWxpdHkgRGlzdHJpYnV0aW9uLCBVbmNlcnRhaW50eSwgYW5kIE1ham9yIFBvd2VyIFdhciwgMTgyMC0xOTY1LiIgaW4gQnJ1Y2UgUnVzc2V0dCAoZWQpIFBlYWNlLCBXYXIsIGFuZCBOdW1iZXJzLCBCZXZlcmx5IEhpbGxzOiBTYWdlLCAxOS00OC4gIAoKUGFsbWVyLCBHbGVubiwgVml0byBEJ09yYXppbywgTWljaGFlbCBLZW53aWNrLCBhbmQgTWF0dGhldyBMYW5lLiAgMjAxNS4gICJUaGUgTUlENCBEYXRhIFNldDogUHJvY2VkdXJlcywgQ29kaW5nIFJ1bGVzLCBhbmQgRGVzY3JpcHRpb24uIiAgQ29uZmxpY3QgTWFuYWdlbWVudCBhbmQgUGVhY2UgU2NpZW5jZS4gIEZvcnRoY29taW5nLgogICAgIAoiUGVyc2lhbiBHdWxmIFdhci4iIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYS4gRW5jeWNsb3DDpmRpYSBCcml0YW5uaWNhLCBJbmMuLCBuLmQuIFdlYi4gMTkgQXByLiAyMDE3LiAKICAKIlRoZSBSaW8gUGFjdCBhdCBhIEdsYW5jZS4iIFRoZSBOZXcgWW9yayBUaW1lcy4gVGhlIE5ldyBZb3JrIFRpbWVzLCAyMCBBcHIuIDE5ODIuIFdlYi4gMTkgQXByLiAyMDE3LiAgCiAgIApSb3lkZS1TbWl0aCwgSm9obiBHcmFoYW0uICJXb3JsZCBXYXIgSS4iIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYS4gRW5jeWNsb3DDpmRpYSBCcml0YW5uaWNhLCBJbmMuLCAwOSBEZWMuIDIwMTYuIFdlYi4gMTkgQXByLiAyMDE3LiAgCiAgIApSb3lkZS1TbWl0aCwgSm9obiBHcmFoYW0uICJXb3JsZCBXYXIgSUkuIiBFbmN5Y2xvcMOmZGlhIEJyaXRhbm5pY2EuIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYSwgSW5jLiwgMDMgRmViLiAyMDE3LiBXZWIuIDE5IEFwci4gMjAxNy4KCiJTU0JOIC0gQmFsbGlzdGljIE1pc3NpbGUgU3VibWFyaW5lLiIgV2lraXBlZGlhLiBXaWtpbWVkaWEgRm91bmRhdGlvbiwgMDggQXByLiAyMDE3LiBXZWIuIDIwIEFwci4gMjAxNy4KICAgIAoiVGhlIFVuaXRlZCBTdGF0ZXMgRGVjbGFyZXMgV2FyIG9uIEphcGFuLiIgSGlzdG9yeS5jb20uIEEmRSBUZWxldmlzaW9uIE5ldHdvcmtzLCBuLmQuIFdlYi4gMTkgQXByLiAyMDE3LgoKIlZpZXRuYW0gV2FyIEhpc3RvcnkuIiBIaXN0b3J5LmNvbS4gQSZFIFRlbGV2aXNpb24gTmV0d29ya3MsIDIwMDkuIFdlYi4gMTkgQXByLiAyMDE3LiAgCiAgCldpdHRlLCBHcmlmZi4gIkFmZ2hhbmlzdGFuIFdhci4iIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYS4gRW5jeWNsb3DDpmRpYSBCcml0YW5uaWNhLCBJbmMuLCAxNCBPY3QuIDIwMTYuIFdlYi4gMTkgQXByLiAyMDE3LiAgCgoiVHJlYXR5IG9mIFZlcnNhaWxsZXMuIiBFbmN5Y2xvcMOmZGlhIEJyaXRhbm5pY2EuIEVuY3ljbG9ww6ZkaWEgQnJpdGFubmljYSwgSW5jLiwgbi5kLiBXZWIuIDE5IEFwci4gMjAxNy4KCgoKCgoKCgoK